使用带有Bootstrap-ui模式的ui路由器
我知道这已经被覆盖了很多次,大多数的文章引用了这个代码: 在AngularJS中使用自定义URL的Modal窗口
但我只是不明白。 我根本不觉得这是非常清楚的。 我也发现这个jsfiddle这实际上是伟大的,非常有帮助,除了这不添加url,并允许我使用后退button来closures模式。
编辑:这是我需要帮助。
所以让我试着解释我想要达到的目标。 我有一个表单来添加一个新的项目,我有一个链接“添加新项目”。 我想当我点击“添加新项目”模式popup与我已经创build的“add-item.html”的forms。 这是一个新的状态,所以url更改为/ add-item。 我可以填写表格,然后select保存或closures。 closures,closures模态:p(奇怪)。 但是我也可以点击回到closures模式,并返回到前一页(状态)。 在这一点上,我不需要关于Close的帮助,因为我仍然在努力实现模态的工作。
这是我的代码,因为它代表:
导航控制器:( 这是甚至正确的地方把模式function?)
angular.module('cbuiRouterApp') .controller('NavbarCtrl', function ($scope, $location, Auth, $modal) { $scope.menu = [{ 'title': 'Home', 'link': '/' }]; $scope.open = function(){ // open modal whithout changing url $modal.open({ templateUrl: 'components/new-item/new-item.html' }); // I need to open popup via $state.go or something like this $scope.close = function(result){ $modal.close(result); }; }; $scope.isCollapsed = true; $scope.isLoggedIn = Auth.isLoggedIn; $scope.isAdmin = Auth.isAdmin; $scope.getCurrentUser = Auth.getCurrentUser; $scope.logout = function() { Auth.logout(); $location.path('/login'); }; $scope.isActive = function(route) { return route === $location.path(); }; });
这是我如何激活模式:
<li ng-show='isLoggedIn()' ng-class='{active: isActive("/new-item")}'> <a href='javascript: void 0;' ng-click='open()'>New Item</a> </li>
新item.html:
<div class="modal-header"> <h3 class="modal-title">I'm a modal!</h3> </div> <div class="modal-body"> <ul> <li ng-repeat="item in items"><a ng-click="selected.item = item">{{ item }}</a></li> </ul>Selected:<b>{{ selected.item }}</b> </div> <div class="modal-footer"> <button ng-click="ok()" class="btn btn-primary">OK</button> <button ng-click="close()" class="btn btn-primary">OK</button> </div>
此外,虽然这确实打开一个模式,它不会closures它,因为我不能解决这个问题。
将模态视为一个状态的视图组件是很直观的。 采取一个视图模板,控制器的状态定义,也许一些决议。 每个特征也适用于模态的定义。 更进一步,将状态条目连接到打开模式和状态退出来closures模式,如果你可以封装所有的pipe道,那么你有一个机制,可以像使用ui-sref
或$state.go
input和后退button或更多模态特定的触发退出。
我已经相当广泛地研究了这一点,我的方法是创build一个模态状态提供程序,在configuration模块以定义绑定到模态的状态时,可以类似于$stateProvider
使用。 当时,我特别感兴趣的是通过状态和模态事件来统一对模态解雇的控制,这比你所要求的要复杂得多,所以这里是一个简单的例子 。
关键是使模态成为状态的责任,并使用模态提供的钩子来保持状态与通过范围或其UI的模式支持的独立交互同步。
.provider('modalState', function($stateProvider) { var provider = this; this.$get = function() { return provider; } this.state = function(stateName, options) { var modalInstance; $stateProvider.state(stateName, { url: options.url, onEnter: function($modal, $state) { modalInstance = $modal.open(options); modalInstance.result['finally'](function() { modalInstance = null; if ($state.$current.name === stateName) { $state.go('^'); } }); }, onExit: function() { if (modalInstance) { modalInstance.close(); } } }); }; })
州入境启动模式。 国家退出closures它。 模式可能会自行closures(例如:通过背景点击),所以您必须观察并更新状态。
这种方法的好处是你的应用程序继续主要与状态和状态相关的概念进行交互。 如果您以后决定将模式转换为常规视图,反之亦然,则很less需要更改代码。
这是一个通过将resolve
部分传递给controller
来改进@ nathan-williams解决scheme的provider
:
.provider('modalState', ['$stateProvider', function($stateProvider) { var provider = this; this.$get = function() { return provider; } this.state = function(stateName, options) { var modalInstance; options.onEnter = onEnter; options.onExit = onExit; if (!options.resolve) options.resolve = []; var resolveKeys = angular.isArray(options.resolve) ? options.resolve : Object.keys(options.resolve); $stateProvider.state(stateName, omit(options, ['template', 'templateUrl', 'controller', 'controllerAs'])); onEnter.$inject = ['$uibModal', '$state', '$timeout'].concat(resolveKeys); function onEnter($modal, $state, $timeout) { options.resolve = {}; for (var i = onEnter.$inject.length - resolveKeys.length; i < onEnter.$inject.length; i++) { (function(key, val) { options.resolve[key] = function() { return val } })(onEnter.$inject[i], arguments[i]); } $timeout(function() { // to let populate $stateParams modalInstance = $modal.open(options); modalInstance.result.finally(function() { $timeout(function() { // to let populate $state.$current if ($state.$current.name === stateName) $state.go(options.parent || '^'); }); }); }); } function onExit() { if (modalInstance) modalInstance.close(); } return provider; } }]); function omit(object, forbidenKeys) { var prunedObject = {}; for (var key in object) if (forbidenKeys.indexOf(key) === -1) prunedObject[key] = object[key]; return prunedObject; }
然后像这样使用它:
.config(['modalStateProvider', function(modalStateProvider) { modalStateProvider .state('...', { url: '...', templateUrl: '...', controller: '...', resolve: { ... } }) }]);
我回答了一个类似的问题,并在这里提供了一个例子:
在AngularJS中使用自定义URL的模式窗口
有一个完整的工作HTML和一个链接plunker。
$ modal本身没有close()函数,我的意思是如果你console.log($ modal),你可以看到只有一个open()函数。
closures模式依赖于$ modalInstance对象,你可以在你的modalController中使用。
所以这个: $ modal.close(result)其实不是一个函数!
注意:console.log($ modal); == >>结果:
Object { open: a.$get</k.open() } // see ? just open ! , no close !
有一些方法可以解决这个问题,一种方法是:
首先你必须在你的模态中定义一个控制器,像这样:
$modal.open({ templateUrl: 'components/new-item/new-item.html', controller:"MyModalController" });
接下来,
app.controller('MyModalController',function($scope,$modalInstance){ $scope.closeMyModal = function(){ $modalInstance.close(result); } // Notice that, This $scope is a seperate scope from your NavbarCtrl, // If you want to have that scope here you must resolve it });