ng-repeat没有更新

时间:2016-02-26 22:02:07

标签: angularjs angularjs-ng-repeat

我正在努力解决一个与angularjs和ng-repeat有关的问题,我有一个由ng-repeat生成的表:

<div>
    <select ng-model="item" ng-controller="dropdown"
        ng-change="update(item)">
        <option value="volvo">Volvo</option>
        <option value="saab">Saab</option>
    </select>
    <table ng-controller="repeatTest">
        <tr>
            <td>name</td>
            <td>family name</td>
            <td>score</td>
        </tr>
        <tr ng-repeat="item in list">
            <td>{{ item.name }}</td>
            <td>{{ item.familyName }}</td>
            <td>{{ item.score }}</td>

        </tr>


    </table>


</div>

我的js代码如下:

 var app = angular.module("myModule", []);

 app.service('sharedService', function() {


    this.list = [];

 });
app.controller('dropdown', function($scope, sharedService) {
$scope.update = function(item) {
    if (item == "volvo") {
        sharedService.list = [ {
            name : 'A',
            familyName : 'AA',
            score : '10'
        }, {
            name : 'B',
            familyName : 'BB',
            score : '5'
        } ];

        $scope.list = sharedService.list;
        console.log($scope.list);
    } else {
        sharedService.list = [ {
            name : 'zzz',
            familyName : 'zzz',
            score : '100'
        }, {
            name : 'zz',
            familyName : 'zz',
            score : '70'
        } ];
        $scope.list = sharedService.list;
    }
}

});
app.controller('repeatTest', function($scope, sharedService) {
sharedService.list = [ {
    name : 'xxx',
    familyName : 'xxx',
    score : 'xxx'
}, {
    name : 'xx',
    familyName : 'xx',
    score : 'xx'
} ];

$scope.list = sharedService.list;

});

现在我的问题是在页面加载时生成的表格,并且当我更改选择框时它永远不会改变,因为我将表格绑定到范围内定义的列表,我假设每当范围更改表应该是也受到影响。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

您的示例不需要两个控制器。

只需将下拉控制器分配给父div并删除repeatTest控制器即可。像这样:

<div ng-controller="dropdown">
  <select ng-model="item" ng-change="update(item)">
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
  </select>

  <table>
    <tr>
      <td>name</td>
      <td>family name</td>
      <td>score</td>
    </tr>
    <tr ng-repeat="item in list">
      <td>{{ item.name }}</td>
      <td>{{ item.familyName }}</td>
      <td>{{ item.score }}</td>
    </tr>
  </table>
</div>

因此,如果您使用相同的控制器来处理select和table,则不需要在服务中查看列表变量以进行更改。

您可以通过这种方式解决或实施事件,但我认为这很容易。

这里是正确代码的jsbin:http://jsbin.com/sivapa/edit?html,js,console,output

答案 1 :(得分:2)

您有两个范围,每个控制器一个。通过分配$ scope.list,您实际上是通过引用传递给每个控制器的列表。因此,您应该清理并重新创建数组,而无需重新分配$scope.listsharedService.list,或者您可以:

添加

$scope.sharedService = sharedService;

在两个控制器上并使用ng-repeat="item in sharedService.list"代替,您将获得更新。

您当前解决方案无法正常工作的原因是您每次调用update时都在创建新数组。这意味着另一个控制器的列表仍将保持对原始/上一个数组的引用。

每次避免创建新数组的示例:

var result = [];
if (item == "volvo") {
    result = [ {
        name : 'A',
        familyName : 'AA',
        score : '10'
    }, {
        name : 'B',
        familyName : 'BB',
        score : '5'
    } ];
} else {
    result = [ {
        name : 'zzz',
        familyName : 'zzz',
        score : '100'
    }, {
        name : 'zz',
        familyName : 'zz',
        score : '70'
    } ];
}

//Clear array
sharedService.list.splice(0,sharedService.list.length);
//Copy values from result into existing array
sharedService.list.push.apply(sharedService.list, result);

请注意,这是未经测试的。而且你还必须在某处完成$ scope.list的初始分配。

答案 2 :(得分:2)

'repeatTest'控制器没有任何方式知道服务数据已经改变......除非你告诉它注意这一点。试试这个版本的控制器:

 app.controller('repeatTest', function($scope, sharedService) {

   $scope.list = sharedService.list;

   $scope.$watch(function() {
       return sharedService.list;
     },
     function(o, n) {
       if (o != n) $scope.list = n
     });
 });

此外,由于您的下拉控制器不会直接影响repeatTest中的列表,因此您无需更新该控制器中的$ scope.list:

app.controller('dropdown', function($scope, sharedService) {
   $scope.update = function(item) {
     console.log(item);
     if (item == "volvo") {
       sharedService.list = [{
         name: 'A',
         familyName: 'AA',
         score: '10'
       }, {
         name: 'B',
         familyName: 'BB',
         score: '5'
       }];
     } else {
       sharedService.list = [{
         name: 'BMW',
         familyName: 'Germany',
         score: '100'
       }, {
         name: 'Frari',
         familyName: 'America',
         score: '100'
       }];
     }
   }
   // Do a little initialization
   $scope.item="volvo";
   $scope.update($scope.item);
 });

这是一个插件:http://plnkr.co/edit/42snC2WyfdKfNzrIKA0o