[英]Angular $watch nuance and factory not reflecting state change?
我很難理解為什么工廠在以下六種情況下不會將對原語的更改(以單例形式)反映為對象,但有時會向對象反映。
我有這個工廠:
angular.module('my.module).factory('myfactory', FactoryFunction);
function FactoryFunction(){
var primitiveVariable = false;
function togglePrimitive(){
primitiveVariable = !primitiveVariable
}
var dummyObject = {
isTrue = false;
}
function toggleObject(){
dummyObject.isTrue = !dummyObject.isTrue;
}
var myFactory = {
toggleObject: toggleObject,
dummyObject: dummyObject,
togglePrimitive: togglePrimitive,
primitiveVariable: primitiveVariable
}
return myFactory
}
我也有這個指令
angular.module('my.module).directive('myDirective', DirectiveFunction);
DirectiveFunction.$inject['myFactory'];
function DirectiveFunction(){
return {
restrict: 'A',
scope:{},
link: function(scope, element, attributes, nullcontroller, nulltranslcude){
//watch1 WONT RUN
//watched is undefined even if myFactory.togglePrimitive() runs
scope.$watch(myFactory.primitiveVariable, function(){
//do stuff
});
//watch2 WONT RUN
//watched is undefined even if myFactory.togglePrimitive() runs
scope.$watch(function(){return myFactory.primitiveVariable}, function(){
//do stuff
});
//watch3 WONT RUN
//not returning something by calling togglePrimitive()?
scope.$watch(myFactory.togglePrimitive(), function(){
//do stuff
});
//watch4 WILL RUN
//but now I am not even running the function...?
scope.$watch(myFactory.togglePrimitive, function(){
//do stuff
});
//watch5 WONT RUN
scope.$watch(myFactory.dummyObject.isTrue, function(){
//do stuff
});
//watch6 WILL RUN
//... seriously??
//is myObj.val and function(){return myObj.val} NOT the same?
scope.$watch(function(){return myFactory.dummyObject.isTrue}, function(){
//do stuff
});
}
}
}
我的問題是,為什么watch1,watch2,watch3,watch5在watch4,wantch6不能工作?
我對為什么會這樣感興趣。 這是設計選擇嗎? 什么目的?
我也想補充一點,function(){return myFactory.primitiveValue}不能作為監視表達式,而function(){return myFactory.dummyObject.isTrue}可以作為監視表達式。 有誰知道為什么這種偏見發生在原始對象與對象的原始屬性之間? 它們都是原語。 當來自工廠功能的console.log更新原語時,它反映了更改。 當表達式中的console.log返回原語(在$ watch中)時,它不反映更改。
jsFiddle: https ://jsfiddle.net/b0svnjqf/21/
任何人都可以照到的光,我將不勝感激。
這是因為watch表達式采用表示屬性的字符串或可以在該作用域上求值的表達式,或者采用返回值的函數getter,該值用於每個摘要周期的臟檢查。
因此,例如:
scope.$watch(myFactory.primitiveVariable, function(){
//do stuff
});
監視表達式是myFactory.primitiveVariable
的值,而不是屬性本身,其中:
scope.$watch(function(){return myFactory.primitiveVariable}, function(){
//do stuff
});
在每個摘要循環中運行作為函數傳入的表達式getter進行臟檢查,這將在那時返回該屬性的值。
同樣,當您這樣做時:
scope.$watch(myFactory.togglePrimitive, function(){
//do stuff
});
您將傳遞給函數togglePrimitive
的引用作為watch表達式,它可以是一個getter,但實際上並沒有從那里返回任何內容,因此您的watch listener不會在1次迭代后運行。
說明文件 :
watchExpression:function()| 串
在每個$ digest循環上評估的表達式。 返回值的更改會觸發對偵聽器的調用。
字符串:作為表達式求值
function(scope):以當前范圍為參數調用。
除此之外,沒有任何必要更改變量primitiveVariable
並希望將更改神奇地反映在myFactory.primitiveVariable
它們兩者都是不同的,並且由於它們是原始對象,因此也不會保留引用。
function FactoryFunction(){
var myFactory ,
dummyObject = {
isTrue = false;
};
function togglePrimitive(){
//Set the value directly on the factory instance
myFactory.primitiveVariable = !myFactory.primitiveVariable
//or even this.primitiveVariable = !this.primitiveVariable;
//But better not to assume "this" as much as you can
}
function toggleObject(){
//This is fine as you are modifying property on the reference and the same reference has been set to the dummyObject property of myFactory
dummyObject.isTrue = !dummyObject.isTrue;
//or this.dummyObject.isTrue = !this.dummyObject.isTrue;
}
myFactory = {
toggleObject: toggleObject,
dummyObject: dummyObject, //this should be fine unless you overwrite the variable dummyObject itself
togglePrimitive: togglePrimitive,
primitiveVariable: false //Set the value directly
}
return myFactory;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.