我正在努力解决一个与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;
});
现在我的问题是在页面加载时生成的表格,并且当我更改选择框时它永远不会改变,因为我将表格绑定到范围内定义的列表,我假设每当范围更改表应该是也受到影响。有人可以帮忙吗?
答案 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.list
或sharedService.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);
});