我现在花了一些时间研究一种用AngularJS
来控制模态窗口的通用方法,并且所提出的选项都没有任何附近好的'溶液
我发现了this演示,但是缺点是你必须手动管理和存储模态和跨范围更新它的状态:
scope.$parent[attrs.visible] = true;
此外,如果您必须添加更多功能,例如实际添加带有弹出窗口的项目,该窗口将涉及父页面范围上更难看的代码。
This is the official guide on how to use modals with ui router.
然而,这是使用 ui.bootstrap.modal
我的问题是,对于一个非常简单的问题,是否有任何简单而优雅的解决方案......
例如:
.state('popup', {
url: '/item/add/',
views: {
'popupView': {
templateUrl: "/myPopup.html",
controller: "myPopupController"
}
},
type: 'modal'
})
关闭,重定向,提交等所有内容都在myPopupController
处理。
我不是要解释为什么上面的例子是这样的,或者我应该如何使用它们。我只是想知道是否有人提出了更好的解决方案。
答案 0 :(得分:4)
我已经在ui-router的模态/对话插件上工作了一段时间(利用它和ui-router-extras)。
我正在将一些内部代码移植到一个开源项目中,如果你愿意尝试一下,这对我来说是一个巨大的好处(对我来说当然也是如此)。
我们目前正在生产应用程序中使用内部版本,并且它运行良好。我的目标是使开源版本在消费者API和性能方面更加出色。
var app = angular.module('mod', ['angular.ui.router.modal', /** ui-router + ui-router-extras **/]);
app.config(function ($uiRouterModalProvider) {
$uiRouterModalProvider.config({
viewName: 'my_modal_view_name',
templateUrl: '/path/to/my_modal_wrapper.html',
rootState: 'name_of_my_apps_root_state',
controller: 'my_modal_wrapper_controller',
resolve: {
common: function ($http) {
return $http.get(apiUrl + '/common_modal_settings');
}
}
});
});
让我们来看看不同的部分:
这是您的模态模板所在的ui-view
的名称。您需要在页面中有一个容器,其ui-view
属性指向{{1}的视图与您的常规内容{/ 1}}相邻(示例将在稍后显示)。
该软件包提供了一个指令,可以为您执行此操作
这是所有模态的基础。假设您想要一个具有某些属性的容器,并且$uiRouterModalProvider.viewName
在任何给定的时间点独立于该模态的内部内容。
这是应用程序中根状态的名称。重要的是,这与保存 root ui-view
元素和模态$scope
元素的状态匹配。
您的普通模态控制器的名称。也可以是一个函数(虽然我总是会推荐一个可以单独进行单元测试的命名控制器)。
每个模态的通用解析块。这与每个模态状态自己的解析块相互依赖。 关于做出决议的API和行为仍在不断变化。
现在已经配置了基本行为,这就是注册模态的方式:
ui-view
ui-view
函数将注册一个状态并引用modalProvider中设置的常用设置,并将给定的状态定义转换为最终状态对象,如下所示:
.modalState('home.mySuperModal', {
url: '/my-super-modal',
templateUrl: 'superModal.html',
controller: 'SuperModalController'
});
.modalState
现在设置了模态包装器的容器。 但内心的内容呢?
这是另一个指令发挥作用的地方; .state('home.mySuperModal', {
url: '/my-super-modal',
views: {
'modal_view_name@root_state': {
templateUrl: 'modal_wrapper.html',
controller: 'ModalWrapperController'
}
},
$$originalState: {
templateUrl: 'superModal.html',
controller: 'SuperModalController'
}
});
。这需要出现在包装模式模板中。就这样:
<!-- The outermost ui-view element -->
<html>
<body ng-app="app">
<div ui-view></div>
</body>
</html>
<!-- The content for the root state of your application {living inside the outermost ui-view directive} -->
<div>
<ui-view></ui-view>
<ui-modal-view></ui-modal-view>
</div>
之前的一些最后的注释(如果)你想要这样做:
uiModalFill
属性以及$ state.resolve与常见modal.resolve共存的方式。 所以,如果我没有成功地吓跑你,那就去看看GitHub并抓住 angular-ui-router-modal 搏一搏。如果您需要任何帮助,我可以在GitHub和/或SO上随时使用。
或者,如果你想纠缠于编写一些文档。我完全理解这一点。
答案 1 :(得分:0)
很好地显示一个指令并不是通过指令以声明方式很好地完成的。通过路由器/状态处理的解决方案也不是我个人所做的。
我的方法是使用Angular Service处理模态。通过服务,您可以强制打开您的模态。
您已经提到ui.bootstrap.modal,我认为这是一个非常好的解决方案。但它也非常灵活。
我使用方法dialogService
创建了一个简单的openConfirmDialog
,它有自己的控制器:
(function() {
'use strict';
angular.module('app').factory('dialogService', dialogService);
function dialogService($modal) {
return {
openConfirmDialog: openConfirmDialog
};
function openConfirmDialog(texts, props) {
texts = texts || {};
texts = angular.extend({
title: '',
okText: 'Yes',
cancelText: 'No',
bodyText: ''
}, texts);
props = props || {};
props = angular.extend({
okClass: 'btn-primary',
cancelClass: 'btn-default'
}, props);
return $modal.open({
templateUrl: 'dialogconfirm.html',
controller: ConfirmController,
controllerAs: 'vm',
resolve: {
texts: function() {
return texts;
},
props: function() {
return props;
}
}
}).result;
}
function ConfirmController($modalInstance, texts, props) {
var vm = this;
vm.texts = texts;
vm.props = props;
vm.ok = function() {
$modalInstance.close();
};
vm.cancel = function() {
$modalInstance.dismiss();
};
}
}
}());
这可以直接在我的控制器中使用:
vm.openDialog = function() {
dialogService.openConfirmDialog({
bodyText: 'Do you really want to close me'
});
};
这是一个有效的Plunker
使用此解决方案,我不必使用模型代码污染我的控制器和/或HTML视图。模态代码封装得非常好。
答案 2 :(得分:0)
您是否查看了AngularStrap http://mgcrea.github.io/angular-strap/#/modals?
您可以传入x[2,2] <-1
,您可以将控制器绑定到模态实例,从而为您提供完全控制(通过在模态模板的顶级元素上设置y <- x
)。 / p>
您可以通过templateUrl
以编程方式触发模态,或使用ng-controller="ModalCtrl"
指令在html中设置属性。