7

我试图理解 Angular 世界和非 Angular 世界之间的交互。

给定一个声明如下的指令:

<dir1 id="d1" attr1="100"/>

如果角度之外的代码以这种方式更改指令:

$("#d1").attr("attr1", 1000);

指令如何知道其属性之一已更改?

4

2 回答 2

8

最好在指令内进行此更改。如果出于某种原因,这是不可能的,那么有几个选择。

在应用程序之外,获取对应用程序内任何 DOM 元素的引用。使用该引用,您可以获取对其范围的引用。您可以将元素与 id 一起使用d1。例如:

var domElement = document.getElementById('d1');
var scope = angular.element(domElement).scope();

这里有几个选项:

选项1

修改模型而不是直接更改视图。在链接函数中,将初始属性值存储在范围变量中,例如:

scope.myvalue = attrs.attr1;

然后您可以更改应用程序外部的值(使用上面对范围的引用),例如:

scope.$apply(function(){
    scope.myvalue = 1000;
    console.log('attribute changed');
});

这是一个小提琴

选项 2

如果直接使用 jQuery 操作视图,我不知道任何使用$observe,$watch或隔离范围绑定到将起作用的属性,因为它们都绑定到属性表达式本身,只有一次,当链接函数是第一次运行。更改值将导致这些绑定失败。因此,您必须$watch使用 DOM 元素本身的属性(而不是 through attrs):

scope.$watch(function(){         
    return $(el).attr('attr1');    // Set a watch on the actual DOM value
}, function(newVal){
    scope.message = newVal;
});

然后您可以更改应用程序外部的值(使用上面对范围的引用),例如:

scope.$apply(function(){
    $("#d1").attr("attr1",1000);
});

这是一个小提琴

于 2013-06-18T02:43:23.853 回答
1

使用Web 组件库,例如Mozilla 的 x-tagsGoogle 的 Polymer。此选项无需在$scope.$apply每次属性更改时手动调用即可工作。

我使用 x-tags 是因为它们支持更广泛的浏览器。在定义新的自定义标签(指令)时,您可以将选项设置lifecycle.attributeChanged为回调函数,每次更改参数时都会触发该函数。

官方文档不是很有帮助。但是通过反复试验和深入研究代码,我设法找出了它是如何工作的。

回调函数的上下文(this对象)是元素本身。属性发生变化的那个。回调可以接受三个参数:

  • name– 属性的名称,
  • oldValue
  • newValue——这些不言自明。

所以现在,言归正传:

编码

这将观察属性的变化:

xtag.register('dir1', {
    lifecycle: {
        attributeChanged: function (attribute, changedFrom, changedTo) {
            // Find the element's scope
            var scope = angular.element(this).scope();

            // Update the scope if our attribute has changed
            scope.$apply(function () {
                if (attribute == 'attr1') scope.style = changedTo;
            });
        }
    }
});

回调仅在参数的值实际更改attributeChanged时触发。要获得它们的初始值,您需要手动扫描批次。最简单的方法似乎是在定义指令时:

myApp.directive('dir1', function () {
    return {
        ... ,
        link: function (scope, element, attributes) {
            scope.attr1 = element[0].getAttribute('attr1');
        }
    };
});
于 2014-06-20T19:59:44.363 回答