如何在angularjs指令中观察属性

How to watch an attribute in an angularjs directive?

本文关键字:观察 属性 指令 angularjs      更新时间:2023-09-26

在我尝试让angularjs和d3js顺利地一起工作时,当我试图在指令中查看属性值时,我遇到了麻烦。让我用这两个简单的指令来说明:

.directive('attr1', function($compile) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      var attr3val = 0;
      d3.select(element[0])
        .attr('attr2', true)
        .attr('attr3', attr3val)
        .on('click', function() {
          d3.select(element[0])
            .attr('attr3', function() {
              attr3val++;
              console.log("new attr3 value is", attr3val);
              return attr3val;
            });
        });
      element.removeAttr("attr1");
      $compile(element)(scope);
    }
  };
})
.directive('attr2', function() {
  return {
    restrict: 'A',
    scope: {
      attr3: "=attr3"
    },
    link: function(scope, element, attrs) {
      scope.$watch('attr3', function() {
        console.log('attr3 modification trigger');
      });
    }
  };
});

它们在这里显示在操作中-必须激活控制台日志才能清楚地了解发生了什么。

在这个线程之后,我使用$compile,以便attr2指令在DOM被d3调用修改后有效地绑定。然后我想看看另一个属性(attr3)的变化。在attr2中使用私有作用域,我认为这是可能的,但我一定是做错了什么,因为蓝色方块中的单击确实更新了属性值,但没有触发手表。

也许DOM属性不是"可观察的"?这些是唯一可行的解决方案吗?

提前感谢你的热心帮助!

<标题>编辑

下面显示的使用$broadcast的解决方案严格来说是有效的,但是如果属性对许多元素都是通用的,那么它是无效的,我想专门观察一个。因此,我将对使用jQuery的函数求值进行$watch,如下所示。

如果你想$观察一个属性,你可以使用$observe:

link: function(scope, element, attrs) {
  attrs.$observe('attr3', function(newValue) {
    console.log('attr3 is ', newValue);
  });
}

解决这个问题的一种方法是在指令中通过$broadcast()创建自定义作用域事件,然后在接收指令中附加一个侦听器。

恰好

.directive('attr1', function($compile) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      var attr3val = 0;
      d3.select(element[0])
        .attr('attr2', true)
        .attr('attr3', attr3val++)
        .on('click', function() {
          d3.select(element[0])
            .attr('attr3', attr3val++);
            scope.$broadcast('attr3-change', attr3val);
        });
      element.removeAttr("attr1");
      $compile(element)(scope);
      scope.$broadcast('attr3-change', attr3val);
    }
  };
})
.directive('attr2', function() {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      scope.$on('attr3-change', function(event, args) {
        console.log(args);
      })
    }
  };
});