问题描述
我还在学习AngularJS。
我用于加载角度对象的JS文件中具有以下功能:
app.controller("myController", ['$scope', '$compile', function ($scope, $compile) {
var $theContainer = $('.container123');
...
this.loadStuff = function () {
$compile('<layout-withbars></layout-withbars>')($scope, function (clonedElement, $scope) {
$theContainer.html(clonedElement); // **this line is where my tests show a runtime issue **
setTimeout(function () {
$('.progress-bar').each(function () {
var $bar = $(this);
$bar.css('width', $bar.attr('aria-valuenow') + '%');
});
}, 1500);
});
};
}]);
该指令本身可以正确加载,其中包含引导进度条。 此“ loadStuff”函数的目标是加载指令,然后使用默认的引导程序过渡使进度条从0%完成更改为X%完成。
如果我在页面上调用此块( 块1 ),则会触发我需要的行为:
$('.progress-bar').each(function () {
var $bar = $(this);
$bar.css('width', $bar.attr('aria-valuenow') + '%');
});
layout-withbars.html:
<div ng-repeat="aProgressbar in progressbars" class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="{{aProgressbar.complete}}" style="width: 0%;">
</div>
</div>
问题:
我必须在对块1的控制器调用周围附加“ setTimeout”函数。 我这样做是因为经过一些测试,我相信$ compile服务指令注入/处理在描述的块1被调用后完成。 我在上面的代码中突出显示了它。
这里有一种组织执行时间的方法吗? 在某些情况下,我的1.5秒延迟可能还不够。
我在从$ compile服务中寻找回调函数。 我相信它是“ postLink”。 我尝试实现它,但是还没有运气。
在$ compile服务指令注入/处理完成执行之后,发出块1执行的最佳方法是什么?
顺便说一句,我还在第1块周围尝试了此操作,但没有成功:
$theContainer.html(clonedElement).promise().done(function(){
...
}
1楼
Kirill Slatin
1
2015-08-07 04:05:39
是的,我坚持要删除毫无意义的Jquery代码和$compile
误用。
因此,不需要超时的回调函数。
除了可以手动告诉angular来编译指令之外,还可以通过ng-if
让它出现在DOM中。
非常适合在DOM中动态添加或删除数量有限的指令(在您的情况下为一个)的情况。
<layout-withbars ng-if="showProgress"></layout-withbars>
所以loadStuff
应该只设置$scope.showProgress = true;
请记住,当表达式为falsy
时,与ng-show
相反, ng-if
实际上删除了该元素。
因此,每当它变为truthy
并将元素添加到DOM时,该指令将再次链接。
在指令的link
(或实际上为postLink
)处理程序中postLink
结论与您试图在setTimeout()
实现的处理程序完全相同。
但是,由于存在允许对元素样式进行数据绑定的指令,因此不再需要此操作。
<div class="progress-bar"
role="progressbar"
ng-style="{width: aProgressbar.complete + '%';">
这样,一旦模型中的数据被更新,宽度将被更新。
2楼
The Fabio
0
已采纳
2015-08-07 06:00:37
我不太了解不愿意使用$compile
服务...它没有施加任何其他延迟。
在我的测试中,我观察到它使浏览器仅在使用$compile
调用注入指令时才加载指令模板,因此,加载实际上比使用ng-if
更快。
无论如何,基里尔·斯拉汀(Kirill Slatin)的回答为我指明了正确的方向:
为了在由angular指令生成的DOM元素上执行函数,指令定义为angular的“指令编译” 之前和之后提供了回调函数。 我从得到 。
此处的解决方案是将块1重构为postLink
和preLink
函数中的指令的link
属性。
之后,不再发生执行时间问题:
app.directive('layoutWithbars', function () {
return {
restrict: 'E',
templateUrl: 'layout-withbars.html',
link: {
pre: function preLink(scope, iElement, iAttrs, controller) {
for (var i=0; i< scope.progressBars.length; i++)
scope.progressBars[i].range = 0;
},
post: function postLink(scope, iElement, iAttrs, controller) {
$timeout(function () {
for (var i=0; i< scope.progressBars.length; i++)
scope.progressBars[i].range = scope.progressBars[i].complete;
}, 100);
}
}
};
});
并且指令主体将具有以下数据绑定,因此将更像angularJS:
<div class="progress" ng-repeat="aProgressBar in progressBars">
<div class="progress-bar" role="progressbar"
aria-valuenow="{{aProgressBar.complete}}"
aria-valuemin="0"
aria-valuemax="100"
ng-style="{width: aProgressBar.range +'%'}">
</div>
</div>