我正试图弄清楚如何在数组中的每个元素上设置$scope.$watch
。我只关心每个元素的某些属性。
在我的示例中,每个rental_date
对象都有三个属性:date
、start_time
和stop_time
。无论何时更改start_time
,我都希望将stop_time
设置为start_time
之后的2小时。
$ngResource
调用(使用Angular 1.1.5):
Agreement.show(
id: 5
).$then ((success) ->
$scope.agreement = success.data.agreement
# returns an array of rental dates
$scope.rental_dates = success.data.rental_dates
# $watch goes here
以下是我尝试的$watch
函数的四种变体:
1:
angular.forEach $scope.rental_dates, (date, pos) ->
$scope.$watch date.start_time, ((newval, oldval) ->
$log.info 'watch changed'
$log.info newval
$log.info oldval
), true
2:
angular.forEach $scope.rental_dates, (date, pos) ->
$scope.$watch $scope.rental_dates[pos].start_time, ((newval, oldval) ->
$log.info 'watch changed'
$log.info newval
$log.info oldval
), true
3:
angular.forEach $scope.rental_dates, (date, pos) ->
$scope.$watch 'rental_dates[pos].start_time', ((newval, oldval) ->
# also tried '$scope.rental_dates[pos].start_time'
$log.info 'watch changed'
$log.info newval
$log.info oldval
), true
4:
这确实有效,但目前,我想不出一个优雅的解决方案来只访问我关心的$watch
ing值,而不是访问整个数组。
$scope.$watch 'rental_dates', ((newval, oldval) ->
$log.info 'watch changed'
$log.info newval
$log.info oldval
), true
有人在自己的项目中做过类似的事情吗?
我假设您以某种方式使用ng repeat为数组的每个条目生成UI元素?为这些UI元素中的每个元素分配一个ng控制器。将为每个数组元素实例化控制器。在控制器内部,使用$watch。
<div ng-repeat="rentalDate in rental_dates" ng-controller="RentalDateController">
</div>
然后在你的控制器代码中:
angular.module(...).controller('RentalDateController', function ($scope) {
$scope.$watch('rentalDate.start_time', function (startTime) {
...
});
});
下面是一个小例子:http://plnkr.co/edit/lhJ3MbULmahzdehCxVeM?p=preview
我认为,如果将第一个$watch
参数更改为:'rental_dates['+pos+'].start_time'
($watch将角度表达式作为第一个参数,pos不属于您的范围),那么解决方案3将起作用。
(虽然这应该有效,但我认为这并不是很有效。也许你应该考虑同时更新start_time和stop_time,而不是关注所有开始时间的变化。)
如果您想监视作为集合一部分的对象中的特定字段,如果您在视图中通过ng重复迭代集合的项,并且如果您将要监视的字段绑定到可以进行ng更改的控件,则可以始终使用ng更改处理程序来处理监视方面。例如:
<div ng-repeat="binding in bindings track by $index">
<input ng-model="binding" ng-change="changed(binding)">
</div>
和js:
scope.changed = function(binding){
.....
}