如何在angularjs指令中观察属性?

时间:2014-07-04 11:55:07

标签: javascript angularjs d3.js angularjs-directive

在我尝试使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');
      });
    }
  };
});

它们显示在操作here中 - 必须激活控制台日志才能清楚地了解发生的情况。

this thread之后,我使用$compile,以便在d3调用修改DOM之后有效绑定attr2指令。然后,我想观看另一个属性的更改(attr3此处)。在attr2中使用私有作用域,我认为这是可能的,但我必须做错事,因为蓝色方块中的点击确实会更新属性值,但不会触发监视。

也许DOM属性不是“可观看的”?是唯一可行的解​​决方案here

感谢您提前寻求帮助!

修改

下面显示的使用$broadcast的解决方案正在严格地说,但如果该属性对于许多元素是通用的,则无效,我想特别注意一个。因此,我正在使用jQuery进行函数评估$watch,如here所示。

2 个答案:

答案 0 :(得分:1)

解决此问题的一种方法是在指令中通过$broadcast()创建自定义范围事件,然后将监听器附加到接收指令。

<强> PLUNKER

e.g。

.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);
      })

    }
  };
});

答案 1 :(得分:1)

如果您想要观看属性,可以使用$ observe:

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