Javascript 有没有办法观察AngularJS世界之外触发的属性更改?
我试图理解角度世界和非角度世界之间的相互作用 给出一个这样声明的指令:Javascript 有没有办法观察AngularJS世界之外触发的属性更改?,javascript,jquery,html,angularjs,angularjs-scope,Javascript,Jquery,Html,Angularjs,Angularjs Scope,我试图理解角度世界和非角度世界之间的相互作用 给出一个这样声明的指令: <dir1 id="d1" attr1="100"/> 指令如何知道其某个属性已更改?最好在指令内部进行此更改。如果,无论出于何种原因,这是不可能的,那么有几个选择 在应用程序外部,获取对应用程序中任何DOM元素的引用。使用该引用,然后可以获得对其范围的引用。您可以使用id为d1的元素。例如: var domElement = document.getElementById('d1'); var scope =
<dir1 id="d1" attr1="100"/>
指令如何知道其某个属性已更改?最好在指令内部进行此更改。如果,无论出于何种原因,这是不可能的,那么有几个选择 在应用程序外部,获取对应用程序中任何DOM元素的引用。使用该引用,然后可以获得对其范围的引用。您可以使用id为d1的元素。例如:
var domElement = document.getElementById('d1');
var scope = angular.element(domElement).scope();
以下是几个选项:
选择1
修改模型,而不是直接更改视图。在link函数中,将初始属性值存储在范围变量中,如:
scope.myvalue = attrs.attr1;
然后,您可以更改应用程序外部的值(使用上面对范围的引用),如:
选择2
如果直接使用jQuery操作视图,我不知道是否使用了$observe
、$watch
,或者将隔离范围绑定到将要工作的属性,因为它们都绑定到属性表达式本身,仅在第一次运行链接函数时绑定一次。更改该值将导致这些绑定失败。因此,您必须$watch
DOM元素本身上的属性(而不是通过attrs
):
然后,您可以更改应用程序外部的值(使用上面对范围的引用),如:
使用类似或的Web组件库。此选项在每次属性更改时都不会调用
$scope.$apply
我使用x标签是因为它们支持更广泛的浏览器。定义新的自定义标记(指令)时,可以将选项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');
}
};
});
你是上述代码的创建者吗?或者这是一个外部应用程序正在改变您的DOM?也许就是你想要的。更可能的是,您希望将数据交给Angular代码,让Angular管理DOM更改,而不是反过来。请参阅。我尝试了$apply(),但我无法让它工作。这实际上是无关的;plunk不工作,因为即使在指令中更改了属性,
$observe
也不会触发。原因隐藏在角度源中:“如果给定的属性没有插值,将永远不会调用观察者。”(即,如果它不包含括号“{}”)。尝试在隔离作用域中创建绑定,并改用$watch
。请使用$watch()
查看此新的plunk。这就是你的意思吗?它也不起作用。$watch
需要在一个变量上,现在它在文本“100”上(它不会改变,但只会被覆盖)。另外,请注意,手动检查在两种plunk中都不起作用。我建议使用一个变量来存储原始值,并使用jQuery直接更改变量。那么,您会说指令无法通过DOM操作通知它的一个属性发生了更改吗?
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);
});
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;
});
}
}
});
myApp.directive('dir1', function () {
return {
... ,
link: function (scope, element, attributes) {
scope.attr1 = element[0].getAttribute('attr1');
}
};
});