【问题标题】:AngularJS : Watch scope value of a injected service changed in one directive from another directiveAngularJS:观察注入服务的范围值在一个指令中从另一个指令更改
【发布时间】:2015-09-29 21:15:46
【问题描述】:

考虑以下场景。

有两个相互独立的指令,我想在这两个指令之间共享范围。由于它们不是嵌套的,我不能在指令中使用控制器来共享范围。所以我创建了一个服务并将服务注入到这两个指令中。

因此,当服务的值在一个指令中更改时,我需要在另一个指令中更新相同的值。我怎样才能做到这一点?我希望以有角度的方式正确完成此操作,没有反模式。

这是我迄今为止尝试过的

.directive('d1', ['cData', function() {
  return {
    link: function() {
       // this watch is not working
       scope.$watch( function() {
            return cData.Value;
       }, function(newValue, oldValue) {
            alert(newValue);
       })
       }
  }
})
.directive('d2', ['cData', function() {
  return {
    link: function() {
      element.on('click', function() {              
        cData.Value = false
        scope.$digest();
      });
      // A watch here is working, I have commented it out
      /*scope.$watch( function() {
            return cd.showStatus;
      }, function(newValue, oldValue) {
            alert(newValue)
      })*/
    }
  }
}])
.service('cData', function() {
  this.Value = false;
})

我在指令d2 的点击事件中更新服务的值,我需要在指令d1 中触发监视。可能这不起作用,因为两个指令的范围不同。我该如何实现这一点,非常感谢任何帮助。

更新

指令模板d1

template : '<div ng-class="{show:cData.Value==true}"></div>'

更新{show:cData.Value==true}

我必须在指令d1的事件监听器中再次调用scope.$apply()

希望这是正确的方法。

【问题讨论】:

    标签: javascript angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    您在正确的道路上,但我建议使用$broadcast 而不是添加新的$watch。添加一个新的观察者更像是一个本地范围的解决方案(至少在我看来)。所以这一切都归结为在两个独立对象之间共享数据。你可以这样实现:

    .directive('d1', ['cData', function() {
      return {
        link: function(scope) {
           // this watch is not working
           scope.$on('data:changed', function(e, data) {
              alert(data);
           }
           /*
           scope.$watch( function() {
                return cData.Value;
           }, function(newValue, oldValue) {
                alert(newValue);
           }) */
           }
      }
    })
    .directive('d2', ['cData', '$rootScope', function() {
      return {
        link: function() {
          element.on('click', function() { 
            $rootScope.$broadcast('data:changed', { value: false });             
            // cData.Value = false
            // scope.$digest();
          });
          // A watch here is working, I have commented it out
          /*scope.$watch( function() {
                return cd.showStatus;
          }, function(newValue, oldValue) {
                alert(newValue)
          })*/
        }
      }
    

    }])

    从我的角度来看,这是实现独立对象/指令之间通信的最简洁方式,而且没有太多麻烦。并且代码非常干净和解耦。

    你怎么看?

    【讨论】:

    • 代替data:changed,你可以写任何暗示性的东西
    • 非常感谢这种方法并且正在工作。但是,我必须在事件监听器 ($on) 中调用 $scope.apply() 来更新模型。
    • 是的,因为 element 是一个 jQuery 对象,与 AngularJS 无关。
    • @prbaron - 哪个元素是 jQuery 对象,$on?
    • 不,它是“元素”。它代表您在 jQuery 中的指令。
    【解决方案2】:

    这些指令的 html 怎么样?你可以添加属性吗?因为你可以看这些属性。

    我不喜欢事件传播。

    【讨论】:

    • Andrei Cacio 的方法运行良好。我应该接受这是正确的答案还是有更好的方法可用。 @prbaron
    • 在这种情况下,您能否建议我另一种解决方案? @prbaron
    • 如果我们从性能的角度来看,events$watchers 便宜。观察者在脏检查过程中被触发,因此该函数将在每个摘要周期天气需要或不需要时执行。事件仅按需触发。这是关于这个问题的一个很好的stackoverflow asnwer:stackoverflow.com/questions/19616520/…
    猜你喜欢
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多