[英]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.