正在设置$scope$监视数组中的每个元素



我正试图弄清楚如何在数组中的每个元素上设置$scope.$watch。我只关心每个元素的某些属性。

在我的示例中,每个rental_date对象都有三个属性:datestart_timestop_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:

这确实有效,但目前,我想不出一个优雅的解决方案来只访问我关心的$watching值,而不是访问整个数组。

$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){
      .....
 }

最新更新