Javascript AngularJS指令中未准备好DOM元素';s link()函数

Javascript AngularJS指令中未准备好DOM元素';s link()函数,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我正在创建一个AngularJS指令,该指令中应该有一个基于的图表。问题是C3库没有看到它应该附加到的DOM元素。指令的链接函数如下所示: link: function(scope, element, attrs) { scope.someid = 'id'; scope.chart = c3.generate({ bindto: "#somechart"+scope.someid, data: { columns: [

我正在创建一个AngularJS指令,该指令中应该有一个基于的图表。问题是C3库没有看到它应该附加到的DOM元素。指令的
链接
函数如下所示:

link: function(scope, element, attrs) {
    scope.someid = 'id';
    scope.chart = c3.generate({
        bindto: "#somechart"+scope.someid,
        data: {
            columns: [
                ['data1', 30, 200, 100, 400, 150, 250],
                ['data2', 50, 20, 10, 40, 15, 25]
            ]
        }
    });         
    console.log($("#somechart"+scope.someid).size()); // this is a test, outputs 0
}
该指令的模板中包含以下内容:

<div id="#somechart{{ scope.someid }}">...</div>
。。。
问题是
c3.generate()
bindto
没有看到
#somechartid
console.log()
我已经输入了输出0,这意味着在调用
link
函数时元素不在DOM中

如果我从浏览器控制台调用相同的图表生成代码,或者甚至从某个
ng调用相同的图表生成代码,请单击
,图表将被渲染

有没有办法不用像
$timeout
这样的解决方案来解决这个问题


更新2014-07-15 15:33更改了代码示例,并从指令模板中添加了相关行。

如果要操作尚未生成的dom,请在链接函数中使用$timeout函数。看

你试过这样的东西吗

link: function(scope, element, attrs) {
    scope.chart = c3.generate({
        bindto: element[0],
        data: {
            columns: [
                ['data1', 30, 200, 100, 400, 150, 250],
                ['data2', 50, 20, 10, 40, 15, 25]
            ]
        }
    });         
}

可能使用元素.find('#id')将有助于:

link: function(scope, element, attrs) {
    var item = element.find('#somechartid');
    scope.chart = c3.generate({
        bindto: item,
        data: {
            columns: [
                ['data1', 30, 200, 100, 400, 150, 250],
                ['data2', 50, 20, 10, 40, 15, 25]
            ]
        }
    });         
}

我提到我不想使用
$timeout
,因为这似乎是一个黑客解决方案。对不起,Ups错过了。因此,我也对解决方案感兴趣,
$timeout
$evalAsync
毕竟是这个问题的解决方案@Teq1提到了一个问题,这让我想到和。这里的讨论解释了使用
$evalAsync
$timeout
的问题、解决方案和细节。angularjs文档用于链接功能:“请注意,包含templateUrl指令的子元素将不会被编译和链接,因为它们正在等待其模板异步加载,并且它们自己的编译和链接已暂停,直到发生这种情况。”他们说,链接用于“编译后”“,但超时是必需的。。。他们不太喜欢使用在常见场景中没有用处的示例。@Ventura在加载、解析外部模板并将其注入dom之后,
元素
才存在,直到在“加载”模板之后但在加载
模板URL
之前,才执行链接函数。这是我对该过程最不完整的理解。请您更具体地解释一下为什么链接函数看不到#somechartid?它是加载在导致延迟的模板上,还是加载页面后动态生成的#somechartid?指令的模板由
templateUrl
提供。所讨论的DOM元素存在于模板中,它的
id
属性被指定为
id=“#somechart{{{data.id}}
。您的id属性实际上是否包含一个#在它里面?id=“#somechart{data.id}”。我注意到的另一件事是,您的id属性是通过角度动态设置的,但您引用的是#沙丁鱼“您的页面上实际上可能不存在。页面上的id不包含
。”。那是个打字错误,抱歉,已经修好了。我已经更新了代码并包含了模板中的相关行。这里的问题是我无法在link函数中启动C3图,因为graph
div
还不在DOM中。如果我稍后尝试通过一些
ng单击
或其他方法来完成,它会起作用。可能是重复尝试过的,但不起作用。我查看了C3源代码,它们使用D3的
select()
,而D3又使用
querySelector()
。无论如何,我更感兴趣的是,在Angular中是否有一个本机解决方案,允许我在元素进入DOM后触发事件好的,我已经查看了你提供的链接。
$evalAsync
解决了这个问题!讨论了问题和答案,并解释了问题、解决方案以及使用
$evalAsync
$timeout
的细节。这与Teq1建议的方法非常相似,但不起作用。我很感兴趣在一个“本机”角度解决方案中,它允许我在DOM准备就绪时触发它。