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

Kur*_*ler 13 angularjs

我试图找出如何设置$scope.$watch数组中的每个元素.我只关心每个元素的某些属性.

在我的例子,每个rental_date对象有三个属性:date,start_time,和stop_time.每当start_time改变时,我希望将stop_time其设置为2小时后start_time.

$ngResource(使用呼叫角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
Run Code Online (Sandbox Code Playgroud)

以下是$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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

4:

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

$scope.$watch 'rental_dates', ((newval, oldval) ->
  $log.info 'watch changed'
  $log.info newval
  $log.info oldval
), true
Run Code Online (Sandbox Code Playgroud)

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

vsp*_*vsp 27

我假设你以某种方式使用ng-repeat为数组的每个条目生成UI元素?为每个UI元素分配ng-controller.将为每个数组元素实例化控制器.在该控制器内,使用$ watch.

<div ng-repeat="rentalDate in rental_dates" ng-controller="RentalDateController">
</div>
Run Code Online (Sandbox Code Playgroud)

然后在您的控制器代码中:

angular.module(...).controller('RentalDateController', function ($scope) {
    $scope.$watch('rentalDate.start_time', function (startTime) {
        ...
    });
});
Run Code Online (Sandbox Code Playgroud)

这是一个小例子:http://plnkr.co/edit/lhJ3MbULmahzdehCxVeM?p = preview

  • $ scope继承与JavaScript的原型链继承类似:如果在当前作用域中找不到属性或方法,则检查父作用域,依此类推.但是,如果在当前作用域中设置属性,则会覆盖该属性,隐藏父作用域的值.Chrome的Batarang扩展程序可以帮助您调试嵌套作用域. (2认同)

Yan*_*ann 8

我想,如果你改变了第一个解决方案3号将工作$watch参数:'rental_dates['+pos+'].start_time'($手表需要的角度表达作为第一个参数,并且pos是不是你的范围内).

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

  • 在AngularJS中不鼓励使用onChange UI事件处理程序.该模型应该是您的应用程序当前状态的记录.让UI元素将用户更改写入模型,然后对模型更改做出反应. (2认同)

Sri*_*ana 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>
Run Code Online (Sandbox Code Playgroud)

在js中:

 scope.changed = function(binding){
      .....
 }
Run Code Online (Sandbox Code Playgroud)