深度 $观看 AngularJS 中的一个集合
Deep $watch a collection in AngularJS
这是我的对象:
$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);
感谢您的指导。
给你。将值 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>
1) 正如 caramiriel 在评论中发表的那样,您可以将 $watch 与函数参数一起使用;
$watch(
function(){
var calculatedVal = /*make all required checks*/;
return calculatedVal;
},
function(newVal){
$scope.canExit = true;
}
);
2) 更好的选择是完全避免 watch 并使用 events/callbacks 这样的 ng-change;它更高效,更易于阅读;
这是我的对象:
$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);
感谢您的指导。
给你。将值 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>
1) 正如 caramiriel 在评论中发表的那样,您可以将 $watch 与函数参数一起使用;
$watch(
function(){
var calculatedVal = /*make all required checks*/;
return calculatedVal;
},
function(newVal){
$scope.canExit = true;
}
);
2) 更好的选择是完全避免 watch 并使用 events/callbacks 这样的 ng-change;它更高效,更易于阅读;