【问题标题】:Deep $watch a collection in AngularJS [duplicate]Deep $watch AngularJS 中的一个集合 [重复]
【发布时间】:2017-01-18 09:15:24
【问题描述】:

这是我的对象:

$scope.steps = {
        service: {
            selected_service: '',
            selected_month: '',
            selected_year: '',
            selected_day: ''
        },
        payment: {
            selected_dd_type: '',
            cc: {
                selected_card_type: '',
                credit_card_number: '',
                name_on_card: '',
                expiry_month: '',
                expiry_year: ''
            },
            bank_acc: {
                bsb_number: '',
                account_number: '',
                account_holder_name: ''
            }
        },
        agreement: {
            agreement_acceptance: false
        }
    }

这里是$watchCollection

$scope.$watchCollection('steps.service', function(newVal, oldVal) {
        $scope.canExit = true;
    });

    $scope.$watchCollection('steps.payment', function(newVal, oldVal) {
        $scope.canExit = true;
    }, true);

    $scope.$watchCollection('steps.payment.cc', function(newVal, oldVal) {
            $scope.canExit = true;
    }, true);

    $scope.$watchCollection('steps.payment.bank_acc', function(newVal, oldVal) {
            $scope.canExit = true;
    }, true);

    $scope.$watchCollection('steps.agreement', function(newVal, oldVal) {
            $scope.canExit = true;
    }, true);

一切正常。

$watch$scope.steps 对象必须有更好的方法。

如果我 $watch steps 它不会工作。我猜 Angular 看不够深入

 $scope.$watchCollection('steps', function(newVal, oldVal) {
                $scope.canExit = true;
        }, true);

感谢您的指导。

【问题讨论】:

    标签: javascript angularjs angularjs-scope watch


    【解决方案1】:

    给你。将值true 作为$watch 中的第三个选项传递:

    $scope.$watch('steps', function(newValue, oldValue) {
         // callback on deep watch
         $scope.canExit = true;
    }, true);
    

    此外,请确保在手表内添加 if 条件,因为当您将值分配给 $scope.steps 时也会触发手表。

    工作示例:

    var app = angular.module("sa", []);
    
    app.controller("FooController", function($scope) {
      $scope.canExit = false;
    
      $scope.steps = {
        service: {
          selected_service: '',
          selected_month: '',
          selected_year: '',
          selected_day: ''
        },
        payment: {
          selected_dd_type: '',
          cc: {
            selected_card_type: '',
            credit_card_number: '',
            name_on_card: '',
            expiry_month: '',
            expiry_year: ''
          },
          bank_acc: {
            bsb_number: '',
            account_number: '',
            account_holder_name: ''
          }
        },
        agreement: {
          agreement_acceptance: false
        }
      };
    
      $scope.reset = function() {
        $scope.canExit = false;
      }
    
      // Using Math.random() just for demo so that the watch can be invoked
      $scope.changeService = function() {
        $scope.steps.service.selected_service = Math.random();
      }
    
      $scope.changeDate = function() {
        $scope.steps.payment.cc.selected_card_type = Math.random();
      }
    
      $scope.changeAgreement = function() {
        $scope.steps.agreement.agreement_acceptance = Math.random();
      }
    
      $scope.$watch('steps', function(newValue, oldValue) {
        if (newValue && (newValue !== oldValue)) {
          // callback on deep watch
          $scope.canExit = true;
        }
      }, true);
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    
    <div ng-app="sa" ng-controller="FooController">
      <button ng-click="changeService()">Change service</button>
      <button ng-click="changeDate()">Change expiry date</button>
      <button ng-click="changeAgreement()">Change agreement</button>
      <br>
      <br>
      <br>Can exit: {{canExit}}
      <button ng-click="reset()">Reset</button>
    </div>

    【讨论】:

    • 谢谢伙计。这完成了工作。那么为什么steps 上的$watchCollection 不起作用?即使我将true 标志添加到$watchCollection
    • 首先$watchCollectiol 不接受任何第三个参数,因此传递任何内容都不会产生任何影响:) 并且文档说$watchCollection Shallow 监视一个对象 所以它在某些情况下不起作用
    • 嗯。再次感谢。我认为这个问题将与另一个问题重复。我现在可能会标记它。干杯。
    • 是的,它与我标记的问题重复。很高兴你发现它重复:)
    【解决方案2】:

    1) 正如在 cmets 中发布的 caramiriel,您可以将 $watch 与函数参数一起使用;

    $watch(
      function(){
         var calculatedVal = /*make all required checks*/;
         return calculatedVal;
      },
      function(newVal){
         $scope.canExit = true;
      }
    );
    

    2) 更好的选择是完全避免观看并使用诸如 ng-change 之类的事件/回调;它更高效,更易于阅读;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-23
      • 2020-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多