In this plunk我在指令中包装了一个Angular UI Modal。从 Controller ,我调用一个方法来打开模式,但是要做到这一点,我需要使用$timeout,否则,DOM尚未完成该指令的呈现。

这似乎可行,但是,如果$timeout过期后仍未完成任何需要完成的操作,会发生什么情况? $timeout可以在开发环境中工作,但在生产中可能会失败。使用$timeout是不好的做法吗?在此示例中如何避免使用它?

的HTML

<div modal control="modalCtl"></div>

Java脚本
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;
});

最佳答案

为了避免使用$timeout,该指令可以在一切准备就绪时通知 Controller 。看一看:

.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>

我们的 Controller :
 $scope.onModalReady = function(){
   $scope.modalCtl.openModal();
 }

Changed Plunker

关于评论@Eduardo La Hoz Miranda


通常,当我们使用0毫秒或不使用任何参数将$timeout初始化为:
 $timeout(function(){
   $scope.modalCtl.openModal();
 });

我们将$scope.modalCtl.openModal()延迟在下一个摘要周期a.e.之前运行。排在最后。因此,在这种情况下,伪指令链接将从头到尾运行1st,只有在您输入$timeout之后才运行。



在生产中,您具有相同的代码。它应该工作。我认为问题出在其他方面。如果您对$timeout不满意,请使用上述我发布的方式。

Your Logged Plunker

10-06 08:08
查看更多