我很难理解为什么工厂不会反映其原语的变化(作为单身人士),但是它会反对...有时......在以下六种情况下。
我有这个工厂:
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 DO工作时不工作?
我对发生这种情况的原因感兴趣。这是一个设计选择吗?目的是什么?
另外我想补充一点,function(){return myFactory.primitiveValue}不能作为监视表达式使用,但是function(){return myFactory.dummyObject.isTrue}可以作为监视表达式使用。有谁知道为什么这种偏差发生在原始对象的原始属性之间?它们都是原始的。当来自更新基元的工厂函数的console.log时,它反映了更改。当来自返回基元的表达式(在$ watch中)的console.log时,它不反映更改。
jsFiddle:https://jsfiddle.net/b0svnjqf/21/
任何人都可以发光,我会非常感激。
答案 0 :(得分:1)
这是因为watch表达式采用表示属性的字符串或可以在该作用域上计算的表达式,或者是函数getter,它返回一个用于脏检查每个摘要周期的值。
例如:
scope.$watch(myFactory.primitiveVariable, function(){
//do stuff
});
watch表达式是myFactory.primitiveVariable
的值,而不是属性本身,其中:
scope.$watch(function(){return myFactory.primitiveVariable}, function(){
//do stuff
});
运行表达式getter在每个摘要周期中作为函数传入,用于脏检查,这将返回当时属性的值。
同样地:
scope.$watch(myFactory.togglePrimitive, function(){
//do stuff
});
您将对函数togglePrimitive
的引用作为可以作为getter的监视表达式传递但是您实际上没有从那里返回任何内容,因此您的监听侦听器将在1次迭代后不会运行。
watchExpression:function()|字符串
在每个$ digest周期计算的表达式。返回值的更改会触发对侦听器的调用。
string:评估为表达式
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;
}