Deep $观看AngularJS中的一个集合

时间:2016-09-10 09:47:50

标签: javascript angularjs angularjs-scope watch

这是我的目标:

$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);

感谢您的指导。

2 个答案:

答案 0 :(得分:3)

你走了。将值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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

1)正如caramiriel在评论中发表的那样,你可以使用$ watch with function argument;

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

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