我刚刚得到了我的指令来引入一个模板来附加到它的元素:
# CoffeeScript
.directive 'dashboardTable', ->
controller: lineItemIndexCtrl
templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
(scope, element, attrs) ->
element.parent('table#line_items').dataTable()
console.log 'Just to make sure this is run'
# HTML
<table id="line_items">
<tbody dashboard-table>
</tbody>
</table>
Run Code Online (Sandbox Code Playgroud)
我还使用了一个名为DataTables的jQuery插件.它的一般用法是这样的:$('table#some_id').dataTable().您可以将JSON数据传递到dataTable()调用以提供表数据,或者您可以将数据放在页面上,然后它将完成其余的工作.我正在执行后者,将行放在HTML页面上.
但问题是我必须在DOM准备就绪之后调用表#line_items上的dataTable().上面的我的指令在模板附加到指令元素之前调用dataTable()方法.有没有办法可以在附加后调用函数?
谢谢您的帮助!
安迪回答后更新1:
我想确保链接方法仅在页面上的所有内容之后调用,因此我更改了指令以进行一些测试:
# CoffeeScript
#angular.module(...)
.directive 'dashboardTable', ->
{
link: (scope,element,attrs) ->
console.log 'Just to make sure this gets run'
element.find('#sayboo').html('boo')
controller: lineItemIndexCtrl
template: "<div id='sayboo'></div>"
}
Run Code Online (Sandbox Code Playgroud)
我确实在div#sayboo中看到了"boo".
然后我尝试我的jquery数据表调用
.directive 'dashboardTable', ->
{
link: (scope,element,attrs) ->
console.log 'Just to make sure this gets run'
element.parent('table').dataTable() # NEW LINE
controller: lineItemIndexCtrl
templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
}
Run Code Online (Sandbox Code Playgroud)
那里没有运气
然后我尝试添加一个时间:
.directive 'dashboardTable', ($timeout) ->
{
link: (scope,element,attrs) ->
console.log 'Just to make sure this gets run'
$timeout -> # NEW LINE
element.parent('table').dataTable()
,5000
controller: lineItemIndexCtrl
templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
}
Run Code Online (Sandbox Code Playgroud)
这很有效.所以我想知道代码的非计时器版本出了什么问题?
par*_*ent 211
如果未提供第二个参数"delay",则默认行为是在DOM完成渲染后执行该函数.因此,不要使用setTimeout,而是使用$ timeout:
$timeout(function () {
//DOM has finished rendering
});
Run Code Online (Sandbox Code Playgroud)
您可以使用"链接"功能,也称为postLink,它在放入模板后运行.
app.directive('myDirective', function() {
return {
link: function(scope, elm, attrs) { /*I run after template is put in */ },
template: '<b>Hello</b>'
}
});
Run Code Online (Sandbox Code Playgroud)
如果您计划制定指令,请阅读此内容,这是一个很大的帮助:http://docs.angularjs.org/guide/directive
虽然我的答案与数据表无关,但它解决了DOM操作的问题,例如jQuery插件初始化,用于在异步方式更新其内容的元素上使用的指令.
可以添加一个监听内容更改(甚至是其他外部触发器)的监视,而不是实现超时.
在我的情况下,我使用这种解决方法初始化一个jQuery插件,一旦完成ng-repeat创建我的内部DOM - 在另一种情况下,我用它来在控制器上更改scope属性后操作DOM.我是怎么做的......
HTML:
<div my-directive my-directive-watch="!!myContent">{{myContent}}</div>
Run Code Online (Sandbox Code Playgroud)
JS:
app.directive('myDirective', [ function(){
return {
restrict : 'A',
scope : {
myDirectiveWatch : '='
},
compile : function(){
return {
post : function(scope, element, attributes){
scope.$watch('myDirectiveWatch', function(newVal, oldVal){
if (newVal !== oldVal) {
// Do stuff ...
}
});
}
}
}
}
}]);
Run Code Online (Sandbox Code Playgroud)
注意:在my-directive-watch属性中,不仅可以将myContent变量强制转换为bool,而是可以想象那里有任意表达式.
注意:像上例中隔离范围只能在每个元素上执行一次 - 尝试在同一元素上使用多个指令执行此操作将导致$ compile:multidir错误 - 请参阅:https://docs.angularjs.org /错误/ $编译/ multidir
回答这个问题可能要迟到了.但仍有人可能从我的答案中获益.
我有类似的问题,在我的情况下,我无法更改指令,因为它是一个库,更改库的代码不是一个好习惯.所以我所做的是使用一个变量来等待页面加载并使用ng-if在我的html中等待呈现特定元素.
在我的控制器中:
$scope.render=false;
//this will fire after load the the page
angular.element(document).ready(function() {
$scope.render=true;
});
Run Code Online (Sandbox Code Playgroud)
在我的HTML(在我的情况下,html组件是一个画布)
<canvas ng-if="render"> </canvas>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
159055 次 |
| 最近记录: |