Angularjs 从链接函数范围内访问DOM。$watch:replace set为true vs false

Angularjs 从链接函数范围内访问DOM。$watch:replace set为true vs false,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我需要在我的链接函数中操作DOM 我注意到,当我将replace设置为false时,我可以访问DOM() //指令体 返回{ 限制:“A”, 替换:false, 范围:{ 酒吧:“@myDir” }, 模板:“foo-bar为{{bar}}”, 链接:功能(范围、元素、属性){ 范围$watch('myDir',函数(值){ log('In watch-scope.bar:',scope.bar'); log('DOM accesible?',$(“#”+scope.bar).length==1

我需要在我的链接函数中操作DOM

我注意到,当我将replace设置为false时,我可以访问DOM()

//指令体
返回{
限制:“A”,
替换:false,
范围:{
酒吧:“@myDir”
},
模板:“foo-bar为{{bar}}”,
链接:功能(范围、元素、属性){
范围$watch('myDir',函数(值){
log('In watch-scope.bar:',scope.bar');
log('DOM accesible?',$(“#”+scope.bar).length==1);
});
}
};
但当我把它设为真时,我不能()

返回{
限制:“A”,
替换:正确,
范围:{
酒吧:“@myDir”
},
模板:“foo-bar为{{bar}}”,
链接:功能(范围、元素、属性){
范围$watch('myDir',函数(值){
log('In watch-scope.bar:',scope.bar');
log('DOM accesible?',$(“#”+scope.bar).length==1);
});
}
};
为什么在“替换”处于启用状态时无法访问DOM?我在文档中没有发现任何东西表明这两种情况之间存在差异

从“链接上的文档”功能可以看出,DOM在链接过程之后是可用的:()

后链接功能 链接子元素后执行在后期链接功能中进行DOM转换是安全的。


请注意,在我的作用域中,$watch实际上是在调用一个jQuery插件,该插件期望DOM在那里,而不是通过$()

直接访问元素。在本例中,您的问题是当运行
链接
函数时,元素尚未连接到DOM。这并不是你要做什么的问题;问题在于,您试图通过jQuery选择器而不是通过传递给
链接
函数的
元素
对象来访问元素,这违反了最佳实践。试着使用
元素
对象,我想你会发现你的代码突然工作了


但是指令方法的执行顺序有一些警告,因此在某些情况下,这仍然不起作用,但在基本指令中不太可能遇到它们。同样,您应该阅读以更好地理解AngularJS如何处理指令。

在本例中,您的问题是当运行
链接时,元素尚未连接到DOM。这并不是你要做什么的问题;问题在于,您试图通过jQuery选择器而不是通过传递给
链接
函数的
元素
对象来访问元素,这违反了最佳实践。试着使用
元素
对象,我想你会发现你的代码突然工作了


但是指令方法的执行顺序有一些警告,因此在某些情况下,这仍然不起作用,但在基本指令中不太可能遇到它们。同样,你应该阅读以更好地理解AngularJS如何对待指令。

旁注-你可能已经意识到这一点,但在你的例子中,
ng repeat=“bar in foo”
应该在
li
上,而不是
ul
上,谢谢@AlexOsborn我更新了fiddlesSide注释-你可能已经意识到了这一点,但在您的示例中,
ng repeat=“bar in foo”
应该在
li
上,而不是
ul
谢谢@AlexOsborn我在代码中更新了小提琴,我正在调用手表中的一个函数,该函数期望dom在那里。我通过控制台日志来显示函数所经历的DOM状态,即DOM在链接函数中有时可用,有时不可用。您不能这样做。AngularJS不保证在
链接
函数运行时将节点附加到DOM。根据您的使用情况,
postLink
函数可能工作得更好。但是我不能在不知道您要做什么的情况下说得更具体。我正在使用highcharts jQuery插件,它将svg图表呈现为div。我正在输入图表div,其中ng repeat绑定到一个包含所有图表的模型。在watch函数中,我调用了highcharts。如果div在那里,它就会工作,如果没有,它就会失败。我也使用compile postLink进行了尝试,但没有成功,因为我将图表id作为属性传递(这是scope.bar在示例中所表示的)。我不是Highcharts专家,但看起来您可以传递对DOM元素的引用:。也就是说,只需传递
元素,而不是
scope.bar
。这行吗?不,它给了我:Error:“undefined”不是Safari中的函数(计算“a.setAttribute(b,c)”),TypeError:Object[Object Object]在ChromeIn我的代码中没有方法“setAttribute”。我正在调用手表中的一个函数,它希望dom在那里。我通过控制台日志来显示函数所经历的DOM状态,即DOM在链接函数中有时可用,有时不可用。您不能这样做。AngularJS不保证在
链接
函数运行时将节点附加到DOM。根据您的使用情况,
postLink
函数可能工作得更好。但是我不能在不知道您要做什么的情况下说得更具体。我正在使用highcharts jQuery插件,它将svg图表呈现为div。我正在输入图表div,其中ng repeat绑定到一个包含所有图表的模型。在watch函数中,我调用了highcharts。如果div在那里,它就会工作,如果没有,它就会失败。我也使用compile postLink进行了尝试,但没有成功,因为我将图表id作为属性传递(这是scope.bar在示例中所表示的)。我不是Highcharts专家,但看起来您可以传递对DOM元素的引用:。我
//body of directive
return {
    restrict: 'A',
    replace: false,
    scope: {
        bar: '@myDir'
    },
    template: '<div id="{{bar}}">foo bar is <span>{{bar}}</span></div>',
    link: function(scope, element, attr) {
        scope.$watch('myDir', function(value) {
            console.log('In watch - scope.bar: ', scope.bar);
            console.log('DOM accesible? ', $("#"+scope.bar).length == 1);
        });
    }
};
return {
    restrict: 'A',
    replace: true,
    scope: {
        bar: '@myDir'
    },
    template: '<div id="{{bar}}">foo bar is <span>{{bar}}</span></div>',
    link: function(scope, element, attr) {
        scope.$watch('myDir', function(value) {
            console.log('In watch - scope.bar: ', scope.bar);
            console.log('DOM accesible? ', $("#"+scope.bar).length == 1);
        });
    }
};