在数组中的每个元素上设置$ scope。$ watch

时间:2013-08-07 14:51:10

标签: angularjs

我试图弄清楚如何在数组中的每个元素上设置$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

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

$scope.$watch 'rental_dates', ((newval, oldval) ->
  $log.info 'watch changed'
  $log.info newval
  $log.info oldval
), true

有人在他们自己的项目中做过类似的事吗?

3 个答案:

答案 0 :(得分:27)

我假设您以某种方式使用ng-repeat为数组的每个条目生成UI元素?为每个UI元素分配ng-controller。将为每个数组元素实例化控制器。在控制器内部,使用$ 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

答案 1 :(得分:8)

如果您将第一个$watch参数更改为:'rental_dates['+pos+'].start_time'$watch将角度表达式作为第一个参数,并且pos不是你的范围)。

(虽然这应该有效,但我认为这不会真正有效。也许你应该考虑同时更新start_time和stop_time,而不是在所有开始时间观察更改。)

答案 2 :(得分:8)

如果要观察作为集合一部分的对象中的特定字段,并且如果您通过ng-repeat在视图中迭代集合的项目,并且如果您要监视绑定到控件的字段可以进行ng-change,你总是可以使用ng-change处理程序处理观看方面。例如:

 <div ng-repeat="binding in bindings track by $index">
     <input ng-model="binding" ng-change="changed(binding)">
 </div>

和js:

 scope.changed = function(binding){
      .....
 }