繁体   English   中英

角度$ watch细微差别和工厂不反映状态变化吗?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM