使用$ watch更改服务中的数据无法正常工作

时间:2014-08-27 14:27:53

标签: angularjs angularjs-directive

我有角度的以下服务:

myModule.factory("myService", function(){
   return {
      data: [],

      updateData: function(data){
         this.data = data;
      }
   }
});

我还有一个指令和一个使用该服务的控制器:

myModule.controller("myController", ['$scope', 'myService', function($scope, myService){
    this.directiveOptions = {data: myService.data, someOtherData: null};
});

 myModule.directive("myDirective", function(){
     return {
            scope: {
                options: "="
            },
            link: function(scope, element, attrs){
                scope.$watch('options.data', function(newData){
                    alert("data was changed");
                });
            }
        };
});

HTML:

<div ng-controller="myController as ctrl">
    <my-directive options="ctrl.directiveOptions"></my-directive>
</div>

在应用程序的某个时刻,我称之为“updateData”(服务的)。正在调用手表,但我得到的newData是旧数据。

我能想出一个解释为什么手表根本不起作用,但无法解释其当前的行为。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

exlpanation非常简单,让我们一步一步地解决这个问题:

  1. 首先创建myService.data数组。我们将此数组称为A1。
  2. 然后创建控制器并设置this.directiveOptions.data = myService.data = A1
  3. 然后调用myService.updateData()并且myService.data数组接收新值A2。
  4. 看到问题?

    this.directiveOptions.data &#34;指向&#34; (用C语说)到A1。它无法知道实际接收A1的源,形式发生了变化。

    我能想到的两个解决方案:

    1. myService.updateData()应该更新相同的数组,例如截断并用新数据重新填充:

      updateData: function(data){
          this.data.length = 0;
          for( var i=0; i < data.length; i++ ) {
              this.data[i] = data[i];
          }
      }
      
    2. 控制器中的
    3. $watch(myService.data)并采取相应行动:

      // inside the controller
      var self = this;
      $scope.$watch(
          function() { return myService.data; },
          function(newval) {
              self.directiveOptions.data = newval;
          }
      );
      

答案 1 :(得分:0)

我认为问题可能围绕着深入观察,如果数据是数组,可以通过以下几种方式处理:

scope.$watch('options.data', function(newData){
                    alert("data was changed");
                }, true); <--passing in true calls deep watches

或者更好地使用$ watchCollection

观看数据收集