In this plunk我有一个Angular UI Modal包含在一个指令中。从控制器,我调用一个方法来打开模态,但为此我需要使用$timeout
,否则,DOM还没有完成渲染指令。
这似乎有效,但是,如果在$timeout
到期后需要完成的任何事情尚未完成,会发生什么? $timeout
可能在开发环境中有效,但可能在生产中失败。使用$timeout
是不好的做法?如何在这个例子中避免使用它?
HTML
<div modal control="modalCtl"></div>
的Javascript
var app = angular.module('app', ['ui.bootstrap']);
app.controller('myCtl', function($scope,$timeout) {
$scope.modalCtl = {};
$timeout(function(){
$scope.modalCtl.openModal();
},100);
})
.directive('modal', function ($uibModal) {
var directive = {};
directive.restrict = 'EA';
directive.scope = {
control: '='
};
directive.link = function (scope, element, attrs) {
scope.control = scope.control || {};
scope.control.openModal = function() {
scope.modalInstance = $uibModal.open({
template: '<button ng-click="close()">Close</button>',
scope: scope
})
};
scope.close = function () {
scope.modalInstance.close();
};
};
return directive;
});
答案 0 :(得分:7)
为了避免使用$timeout
,指令可以在一切准备就绪时通知控制器。看看:
.directive('modal', function ($uibModal) {
var directive = {};
directive.restrict = 'EA';
directive.scope = {
control: '=',
onReady: '&' // <-- bind `onReady` with `onModalReady`
};
directive.link = function (scope, element, attrs) {
scope.control = scope.control || {};
scope.control.openModal = function() {
scope.modalInstance = $uibModal.open({
template: '<button ng-click="close()">Close</button>',
scope: scope
})
};
scope.close = function () {
scope.modalInstance.close();
};
scope.onReady(); // <-- notify controller
};
return directive;
});
输出HTML:
<div modal on-ready="onModalReady()" control="modalCtl"></div>
我们的控制人员:
$scope.onModalReady = function(){
$scope.modalCtl.openModal();
}
关于评论@Eduardo La Hoz Miranda
你应该对超时感到满意。我会把时间减少到0,因为超时会将你的呼叫发送到事件循环的底部。
通常我们用0毫秒初始化$timeout
或没有参数:
$timeout(function(){
$scope.modalCtl.openModal();
});
我们推迟$scope.modalCtl.openModal()
在下一个摘要周期a.e之前运行。最后排队。因此,在这种情况下,指令链接将从开始到结束运行1,并且仅在您输入$timeout
之后。
$ timeout可能在开发环境中有效,但可能在生产中失败。
在生产中,您拥有相同的代码。它应该工作。我相信问题出在其他方面。如果你对$timeout
使用上面提到的方式没有信心,我发布了。
答案 1 :(得分:1)
当指令的链接功能完成时,它会发出一条消息,表明它已准备就绪。
控制器监听此消息并在收到时显示模态。
代码:
var app = angular.module('app', ['ui.bootstrap']);
app.controller('myCtl', function($scope,$timeout) {
$scope.modalCtl = {};
$scope.$on("hey", function() {
$scope.modalCtl.openModal();
});
})
.directive('modal', function ($uibModal) {
var directive = {};
directive.restrict = 'EA';
directive.scope = {
control: '='
};
directive.link = function (scope, element, attrs) {
scope.control = scope.control || {};
scope.control.openModal = function() {
scope.modalInstance = $uibModal.open({
template: '<button ng-click="close()">Close</button>',
scope: scope
})
};
scope.close = function () {
scope.modalInstance.close();
};
scope.$emit("hey");
};
return directive;
});
答案 2 :(得分:0)
对代码执行的任意等待使用超时通常是不好的。正如您在问题中所述,根据您正在加载的页面的整体上下文,您无法保证在控制器运行时该指令就绪。
这里似乎有太多的抽象层次。有些东西渲染div,当它完全渲染时,会显示一个模态。
仅仅让渲染div的东西创建并显示模态会更有意义吗?