角引导模态控制器范围

Posted

技术标签:

【中文标题】角引导模态控制器范围【英文标题】:Angular bootstrap modal controller scope 【发布时间】:2016-06-03 08:07:05 【问题描述】:

我正在尝试使用 angular bootstrap 来获取模态框。我可以很好地启动模态,但我在解除模态时遇到了一些范围问题。

当我启动模式时,我可以指定一个控制器,我可以从中调用函数,它可以工作,但它似乎是控制器的 副本,没有 $parent 并且没有任何控制器 -局部变量。

我需要访问 $uibModal.open() 的返回值才能关闭模式,所以我试图将它存储在 var modalInstance 中,当我在控制器范围内时它工作正常,但是传递给 $uibModal 服务的控制器副本没有设置局部变量 modalInstance。

我可以通过将返回对象存储在 $rootScope 中来解决这个问题,但这似乎是个坏主意。我错了吗?从传递给 $uibModal 服务的点击处理程序访问 modalInstance 的最佳方法是什么?我可以避免使用 $rootScope 吗?

var app = angular.module('main', ['ui.bootstrap']);

app.controller('MainCtrl', function($scope, $rootScope, $uibModal) 
  var modalInstance;

  $scope.launch = function() 
    console.log('launch');
    modalInstance = $uibModal.open(
      template: '<div>Modal Content - <a ng-click="close()">Close</a></div>',
      controller: 'MainCtrl',
    );

    // Wouldn't need to do this if I could access modalInstance in close handler
    $rootScope.modalInstance = modalInstance;
  

  $scope.close = function () 
    console.log('close');
    console.log(modalInstance);

    // Works, but should I be using $rootScope like this?
    //$rootScope.modalInstance.close();

    // Doesn't work, modalInstance is undefined
    modalInstance.close();
  
);

【问题讨论】:

【参考方案1】:

Angular 在每次使用时都会实例化一个新的控制器实例,模态也是如此。因此,当您指定控制器:'MainCtrl' 时,您是在告诉 Angular,您想为您的模态实例化其中之一,而这很少是您想要的。

相反,您应该为对话框创建一个单独的控制器,它可以在使用 $uibModalInstance 服务关闭时返回值。

var app = angular.module('main', ['ui.bootstrap']);

app.controller('MainCtrl', function($scope, $rootScope, $uibModal) 
  var modalInstance;

  $scope.launch = function() 
    console.log('launch');
    modalInstance = $uibModal.open(
      template: '<div>Modal Content - <a ng-click="close()">Close</a></div>',
      controller: 'DialogCtrl',
    );
    ....

  

);

app.controller('DialogCtrl', function($scope, $uibModalInstance) 
  $scope.theThingIWantToSave = [];
  $scope.cancel = function () 
    $uibModalInstance.close($scope.theThingIWantToSave);
  ;
);

【讨论】:

这是一个简化的示例,但我想从模式中引用 MainCtrl 中的一堆功能,这就是为什么我想使用这个控制器而不是为模态的。假设我在 MainCrtl 中有需要引用的范围函数,那么处理这个问题的最佳方法是什么?我可以交叉引用 MainCtrl 中的一些函数,还是我的原始解决方案更好? 如果你有想要在控制器之外使用的功能,你真的应该把它放在服务中。控制器应该只为 UI 提供真正的绑定并处理 UI 事件,其他一切(数据和逻辑)都应该属于服务。 有趣,我觉得这有点违反直觉,但我想我明白你在说什么。您是否知道有任何文章讨论了将一般功能包装在服务中的想法? 将控制器视为粘在 DOM 部分的一次性小部件,真正的工作发生在工厂/服务中。 Angular 的概念指南是一个很好的介绍:docs.angularjs.org/guide/concepts Angular 的文档可能很难导航,但真的值得花时间浏览。

以上是关于角引导模态控制器范围的主要内容,如果未能解决你的问题,请参考以下文章

如何在服务器端的模态引导程序中进行验证?

AngularJS将数据传递给引导模式

更改模态视图控制器的cornerRadius

Coffeescript不在带有引导程序的rails中的模态窗口中工作

不要在角度模态中保存范围更改

引导模式中的 Laravel ajax 搜索