基于ui.router与ui.bootstrap实现可定制通用模态框的可行性咨询
在UI-Router中实现通用可定制模态框的方案探讨
你的代码实现完全可行!这种把模态框逻辑封装在自定义指令、不在$uibModal里配置controller的思路非常合理,既符合组件化的设计思想,也能让模态框的业务逻辑和视图解耦。不过如果要创建多个模态框,咱们可以通过抽象状态抽离重复代码,打造一个更通用的方案,避免一遍遍写相似的onEnter逻辑。
一、先确认可行性
你当前的代码逻辑是站得住脚的:
- 利用UI-Router的
onEnter钩子在进入状态时触发模态框,这是官方推荐的模态框与路由结合的方式之一; - 自定义指令接管模态框的视图和逻辑,不需要额外配置
controller,这种封装方式能让每个模态框的职责更清晰; - 已经引入
ui.router.modal和ui.bootstrap依赖,环境支持没问题。
二、通用化优化方案(避免重复代码)
为了批量创建模态框状态,我们可以定义一个抽象父状态,把所有模态框共用的逻辑抽离出来,具体的模态框子状态只需要传入专属配置即可:
1. 定义通用抽象模态框状态
这个状态作为所有模态框的父级,负责处理模态框的打开、关闭后的路由跳转等通用逻辑:
{ name: 'parentpage.modal', abstract: true, // 标记为抽象状态,不能直接访问 onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) { // 打开模态框,使用传入的指令名称和配置 const modalInstance = $uibModal.open({ // 动态渲染指定的自定义指令 template: `<${$stateParams.directiveName} modal-config="$stateParams.modalConfig"></${$stateParams.directiveName}>`, // 通用配置,也可以通过$stateParams覆盖 backdrop: $stateParams.backdrop || 'static', size: $stateParams.size || 'md' }); // 处理模态框关闭后的路由跳转,避免停留在模态框路由上 modalInstance.result.finally(() => { $state.go('^'); // 回到父状态(parentpage) }); }] }
2. 创建具体的模态框子状态
每个具体的模态框只需要继承抽象状态,传入自己的指令名称和配置参数,完全不用重复写模态框的打开逻辑:
// 第一个自定义模态框 { name: 'parentpage.modal.first', url: '/first-modal', params: { directiveName: 'mydirective-one', modalConfig: { configOne: 'a', configTwo: 'b' }, size: 'lg' // 可选,覆盖通用状态的size配置 } } // 第二个自定义模态框 { name: 'parentpage.modal.second', url: '/second-modal', params: { directiveName: 'mydirective-two', modalConfig: { configX: 'foo', configY: 'bar' }, backdrop: true // 可选,覆盖通用状态的backdrop配置 } }
3. 自定义指令接收配置
对应的自定义指令只需要通过scope或bindToController接收modalConfig参数,即可实现可定制化:
angular.module('yourApp').directive('mydirectiveOne', function() { return { scope: { modalConfig: '<' // 单向绑定配置参数 }, controller: function($scope) { // 在这里使用$scope.modalConfig.configOne、$scope.modalConfig.configTwo console.log($scope.modalConfig.configOne); // 输出 'a' }, templateUrl: 'path/to/your/mydirective-one-template.html' }; });
三、额外注意点
- 路由状态清理:一定要处理模态框关闭后的路由跳转,不然用户关闭模态框后URL仍停留在模态框路由,刷新页面会再次打开模态框,我们在抽象状态的
finally钩子中已经处理了这一点; - 动态传参:如果需要从父页面传递动态数据到模态框,只需要在调用
$state.go时传入参数即可:// 父页面中打开模态框并传动态参数 $state.go('parentpage.modal.first', { modalConfig: { configOne: dynamicValue, configTwo: anotherDynamicValue } });
内容的提问来源于stack exchange,提问作者Bence Ágocsi Kiss
相关产品推荐
相关产品推荐

