避免在Angular UI Modal中使用$ timeout

ps0*_*604 5 angularjs angular-ui angularjs-directive angular-ui-bootstrap

在这个插件中,我有一个Angular UI Modal包装在一个指令中.从控制器,我调用一个方法来打开模态,但为此我需要使用$timeout,否则,DOM还没有完成渲染指令.

这似乎有效,但是如果需要完成的任何事情在$timeout到期后还没有完成,会发生什么?该$timeout可以在开发环境中工作,但在生产中可能会失败.使用是不好的做法$timeout?如何在这个例子中避免使用它?

HTML

<div modal control="modalCtl"></div>
Run Code Online (Sandbox Code Playgroud)

使用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;
});
Run Code Online (Sandbox Code Playgroud)

Max*_*tin 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;    
});
Run Code Online (Sandbox Code Playgroud)

出HTML:

 <div modal on-ready="onModalReady()" control="modalCtl"></div>
Run Code Online (Sandbox Code Playgroud)

控制器:

 $scope.onModalReady = function(){
   $scope.modalCtl.openModal();
 }
Run Code Online (Sandbox Code Playgroud)

Changed Plunker


关于评论 @Eduardo La Hoz Miranda

你应该对超时感到满意.我会把时间减少到0,因为超时会将你的呼叫发送到事件循环的底部.

通常当我们$timeout用0毫秒初始化或没有参数时:

 $timeout(function(){
   $scope.modalCtl.openModal();
 }); 
Run Code Online (Sandbox Code Playgroud)

我们延迟在队列中的最后一个消化循环ae $scope.modalCtl.openModal()之前运行.因此,在这种情况下,指令链接将从开始到结束运行1,并且只有在您输入后才会运行.$timeout

$ timeout可能在开发环境中有效,但可能在生产中失败.

在生产中你有相同的代码.它应该工作.我相信问题出在其他方面.如果您对$timeout使用上述方式没有信心我发布了.

Your Logged Plunker