Greg Dougherty
Greg Dougherty

Reputation: 3471

Angular ng-repeat on table with data input

The answer appears to be that the two way data binding works if you have an array of objects going to an ng-repeat, but did doesn't work if you have an array of strings.

I wish to provide a UI where users can input multiple recipients. I've got an array of names called "receivers". My thought was I could display a table using ng-repeat, like so:

<table>
    <tr ng-repeat = "receiver in receivers">
        <td><input type = "text" ng-model = "receiver"></td>
        <td><div ng-click = "addRecipient(receiver)">+</div></td>
        <td><div ng-click = "deleteRecipient(receiver)">-</div></td>
    </tr>
</table>

The problem I'm running in to is that I know of no way to get the contents of "receiver" back to my controller, other than from the calls to addRecipient or deleteRecipient. Which makes it hard for me to use that data.

Any suggestions would be greatly appreciated. If there's a better or "more correct" way to do this, I'd love to see it.

Upvotes: 4

Views: 17188

Answers (3)

Fahimeh Ahmadi
Fahimeh Ahmadi

Reputation: 1027

You can use this method on the site

https://stackblitz.com/edit/data-api-rest-angular

I put to use

Upvotes: 0

Nicholas Hirras
Nicholas Hirras

Reputation: 2596

You don't need to do anything extra. Whatever text is typed into the text fields on your page will automatically be present in your $scope.receivers array. I always define my scope variable explicity in my controller.

I have a working example but using a simple object instead of Strings, that could be the issue.

http://plnkr.co/edit/g66KTkDPlWt0xs5EZrrx?p=preview

script:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name="Nick";
  $scope.receivers=[{value:"First"}];

  $scope.addRecipient = function(receiver) {
    $scope.receivers.push({value:""});
  }

  $scope.deleteRecipient = function(receiver) {
    for(var i=0; i<$scope.receivers.length; i++) {
      if($scope.receivers[i] === receiver) {
        $scope.receivers.splice(i, 1);
        break;
      }
    }
  }

  $scope.showme = function() {
    var s = "";
    for(var i=0; i<$scope.receivers.length; i++) {
      s = s + i + ": " + $scope.receivers[i].value + "\n";
    }
    alert(s);
  };

});

html:

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <table>
        <tr ng-repeat = "receiver in receivers">
            <td><input type="text" ng-model="receiver.value"></td>
            <td><div ng-click="addRecipient(receiver)">+</div></td>
            <td><div ng-click="deleteRecipient(receiver)">-</div></td>
        </tr>
    </table>    

    <button ng-click="showme()">Show Me Contents</button>

  </body>

</html>

Upvotes: 5

Aliz
Aliz

Reputation: 756

The problem I'm running in to is that I know of no way to get the contents of "receiver"

If you want to evaluate an expression (or in your case display information for each "receiver") you could use the operator "{{yourExpression}}".

Example : <td>{{receiver.oneAttribute}}</td>

See this documentation for more informations : https://docs.angularjs.org/guide/expression

Upvotes: 1

Related Questions