我现在花了一些时间研究使用 AngularJS
控制模态窗口的通用方法,但没有一个提议的选项接近“好”的解决方案。
指令解决方案
我找到了 this演示,但是它的缺点是您必须手动管理和存储模态的状态并跨范围更新它:
scope.$parent[attrs.visible] = true;
此外,如果您必须添加更多功能,例如实际添加带有弹出窗口的项目,这将在父页面范围内涉及更丑陋的代码。
UI-Router 解决方案
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
中处理。
我不是要解释为什么上面的例子是这样的,或者我应该如何使用它们。我只是想看看是否有人提出了更好的解决方案。
最佳答案
我已经在 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');
}
}
});
});
让我们来看看不同的部分:
View 名称
这是ui-view
的名称,您的模态模板将位于其中。要求您的页面中有一个包含ui-view
的容器指向 $uiRouterModalProvider.viewName
的 View 的属性,该 View 位于您的常规 ui-view
旁边,用于您的常规内容(稍后将显示示例) .
该包提供了一个为您执行此操作的指令
模板网址
这是所有模态框的基础。假设您想要一个具有特定属性的容器,以及一个在任何给定时间点独立于模态的内部内容的 $scope
。
根状态
这是您应用程序中根状态的名称。重要的是,这与保存您的 root ui-view
元素和模态 ui-view
元素的状态相匹配。
Controller
您常用的模态 Controller 的名称。也可以是一个函数(尽管我总是推荐一个可以单独进行单元测试的命名 Controller )。
解决
每个模式的通用解析 block 。这与每个模态状态拥有解析 block 相互依赖。 有关解析的 API 和行为仍在不断变化。
状态注册阶段
现在已经配置了基本行为,这就是注册模态状态的方式:
.modalState('home.mySuperModal', {
url: '/my-super-modal',
templateUrl: 'superModal.html',
controller: 'SuperModalController'
});
.modalState
函数将注册一个状态并引用 modalProvider 中设置的公共(public)设置,并将给定的状态定义转换为最终状态对象,如下所示:
.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
。这需要出现在您的包装模式模板中。因此:
<!-- wrapping modal template -->
<div id="modal_wrapper">
<h1>Some heading. I'm always present!</h1>
<hr>
<ui-modal-fill></ui-modal-fill>
</div>
结论
在(如果)您想尝试一下之前的一些最后说明:
- 许多所需的功能尚未移植/实现。这是一项正在进行的工作。
- 一些 API 在不久的将来可能会发生很大变化,包括但不限于
resolve
属性以及 $state.resolve 与通用 modal.resolve 一起使用的方式。 - 一些样板要求需要更改。 API 应该易于使用(但又灵活),但现在消费者必须填写的详细信息太多。
- 文档实际上不存在。弄清楚幕后实际发生了什么的最好方法是查看源代码(抱歉...)。
那么,如果我没能吓跑你,让你不敢尝试 - 前往 GitHub 并获取 angular-ui-router-modal 并试一试。如果您需要任何帮助,我总是可以在 GitHub 和/或 SO 上找到。
或者如果您只是想缠着我写一些文档。我会完全理解这一点。
关于javascript - Angular 模态窗口(UI-路由器/指令),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31406320/