Angular 模态(ui-路由器)和通用模态架构概念
Angular modals (ui-router) and general modal architecture concepts
我正在开发一个相当复杂的 AngularJS 网络应用程序,但一直无法实现满足我的要求的工作模式/路由机制ui。
情况
我的应用程序具有(简化)以下实体:
- 客户(有 0 个或多个联系人)
- 订单(恰好有 1 个客户)
- 联系人(恰好属于 1 个客户)
在创建新订单期间,可以选择现有客户,也可以创建新客户。在客户的创建过程中,可以选择创建一个新的联系人。
UI / 用户体验解决方案
我研究了几种以 "non-cluttering" 和移动友好的方式正确表示此功能的方法。首先,我试图完全远离模式或弹出窗口,并尝试创建几个 Angular 指令以在页面中动态显示,但这很快就变得太复杂了。新客户的创建存在多个 UI 状态和一些子状态(选项卡),并且其中具有相当复杂的逻辑。
然后我查看了使用单独的浏览器选项卡并使用 localStorage 在它们之间进行通信。然而,这种方法似乎很脆弱,而且对用户来说并不常见。此外,用户应该继续在新选项卡中工作直到完成,然后才能 return 到上一个选项卡。使用单独的浏览器选项卡无法做到这一点。
我看过 Javascript 浏览器弹出窗口,但我也不喜欢那个方向。
从用户的角度来看,我认为最好的方法是使用模态对话框来遵循 UI 流程:
UI流量
+----------+ +------------+ +-----------+
|New Order | - Opens modal -> |New Customer| - Opens modal -> |New Contact|
+----------+ +------------+ +-----------+
^ | ^ |
| OK | OK
| Closes modal and | | Closes modal and |
| selects new customer | | selects new contact |
+----<-----<-------<-----<---+ +----<-----<-------<-----<----+
注意:New Customer 和 New Contact 状态也是自身的状态,可以在常规 window 中打开。
我创建了 Angular-UI-路由器路由为:
- 新订单:app.orders.new
- 新客户:app.customers.new
- 新联系人:app.contacts.new
发展
为了支持多模态架构,我尝试了几种方法:
- 使用Angular UI Bootstrap Modal
- 使用 UI-Router-Extras 方式使用自己的 built Modal windows
需要牢记的一些重要方面:
- 我不需要直接 URL 直接指向模态 window。 URL 可以保持在 "New Customer" 状态。
- 该行为应该是模态的,因此无法在父级上工作 window。
- 它应该能够依次打开和显示多个状态(例如一个模式中的一个向导)
- 按特定顺序打开的多个模态框应按相同顺序关闭。 (后进先出)
1.使用 Angular UI Bootstrap Modal
这种方式似乎很有希望。我创建了一个单独的路由,它使用一些控制器和常规路由的视图:
- Modal.Customers.New
- Modal.Contacts.New
但不幸的是,我很难在模态内打开更多模态并保持先前模态的状态。我使用 UI-Router-Extras Sticky States 来保持后台状态。然而,正如 UI-Router-Extras 所述,Sticky States 仅在每个状态都有自己的 ui-view 时才有效。一个 ui-view 应该事先声明。这是不可能的,因为理论上用户可以在我的应用程序中打开无限量的嵌套模式。
2。使用 UI-Router-Extras 方式使用自己的 built Modal windows
我尝试使用 UI-Router-Extras 的简单模态示例创建一个简单模态而不是 Angular UI 模态,如:http://plnkr.co/edit/qgt0RkEnXDPDTdMJPIfy?p=info
但不幸的是,我遇到了与选项 1 相同的问题。问题是当模态框嵌套时,状态和路由变得过于复杂。
解决方案
我现在真的很纠结什么是最好的方法。我正在考虑显示一个带有 iframe 的模态覆盖 window,它打开一个单独的 UI-Router 路由,例如:Modal.Customers.New,它只显示应用程序的内容(不是菜单酒吧等)。
使用 iframe 时,我可以在父 window 和 iframe 上保留单独的路线和状态信息。我需要执行一些自定义 javascript 以支持将 iframe 缩放为正确的格式,但这是可以接受的。
但它仍然感觉像是一个 "hacked" 解决方案。
我很想听听您的解决方案和见解。
最终我选择了将 iframe 与 Angular UI 模态框结合使用。这种方法让我可以完全灵活地在我的应用程序中使用复杂的路由,并且 Angular UI 的模态屏幕会在不同的屏幕分辨率下自动调整 iframe 的大小。
我已经为模式中使用的所有状态创建了路由,前缀为:modal。而不是应用程序。
这样,我只能使用页面的 "content" 子视图在 Modal 内部显示,并且仍然具有原始控制器和视图的完全可重用性。
唯一棘手的一点是打开多个嵌套模态框时。在那里我必须检查我是处于模式状态还是处于常规状态。使用州名称非常容易:
IsModal() {
return this.$state.current.name.indexOf("modal") == 0;
}
在根框架(非模态视图)上,我收集了数组中所有打开的 Angular UI 模态,如果模态位于视图(非模态)。如果没有,我使用以下方法将 iframe 向上遍历到父范围:
var parentScopeModalService = (<any>parent).angular.element(window.frameElement).scope().MyModalService;
这实际上非常有效,因为所有 iframe 都在同一个域中。
我正在开发一个相当复杂的 AngularJS 网络应用程序,但一直无法实现满足我的要求的工作模式/路由机制ui。
情况
我的应用程序具有(简化)以下实体:
- 客户(有 0 个或多个联系人)
- 订单(恰好有 1 个客户)
- 联系人(恰好属于 1 个客户)
在创建新订单期间,可以选择现有客户,也可以创建新客户。在客户的创建过程中,可以选择创建一个新的联系人。
UI / 用户体验解决方案
我研究了几种以 "non-cluttering" 和移动友好的方式正确表示此功能的方法。首先,我试图完全远离模式或弹出窗口,并尝试创建几个 Angular 指令以在页面中动态显示,但这很快就变得太复杂了。新客户的创建存在多个 UI 状态和一些子状态(选项卡),并且其中具有相当复杂的逻辑。
然后我查看了使用单独的浏览器选项卡并使用 localStorage 在它们之间进行通信。然而,这种方法似乎很脆弱,而且对用户来说并不常见。此外,用户应该继续在新选项卡中工作直到完成,然后才能 return 到上一个选项卡。使用单独的浏览器选项卡无法做到这一点。
我看过 Javascript 浏览器弹出窗口,但我也不喜欢那个方向。
从用户的角度来看,我认为最好的方法是使用模态对话框来遵循 UI 流程:
UI流量
+----------+ +------------+ +-----------+
|New Order | - Opens modal -> |New Customer| - Opens modal -> |New Contact|
+----------+ +------------+ +-----------+
^ | ^ |
| OK | OK
| Closes modal and | | Closes modal and |
| selects new customer | | selects new contact |
+----<-----<-------<-----<---+ +----<-----<-------<-----<----+
注意:New Customer 和 New Contact 状态也是自身的状态,可以在常规 window 中打开。
我创建了 Angular-UI-路由器路由为:
- 新订单:app.orders.new
- 新客户:app.customers.new
- 新联系人:app.contacts.new
发展
为了支持多模态架构,我尝试了几种方法:
- 使用Angular UI Bootstrap Modal
- 使用 UI-Router-Extras 方式使用自己的 built Modal windows
需要牢记的一些重要方面:
- 我不需要直接 URL 直接指向模态 window。 URL 可以保持在 "New Customer" 状态。
- 该行为应该是模态的,因此无法在父级上工作 window。
- 它应该能够依次打开和显示多个状态(例如一个模式中的一个向导)
- 按特定顺序打开的多个模态框应按相同顺序关闭。 (后进先出)
1.使用 Angular UI Bootstrap Modal 这种方式似乎很有希望。我创建了一个单独的路由,它使用一些控制器和常规路由的视图:
- Modal.Customers.New
- Modal.Contacts.New
但不幸的是,我很难在模态内打开更多模态并保持先前模态的状态。我使用 UI-Router-Extras Sticky States 来保持后台状态。然而,正如 UI-Router-Extras 所述,Sticky States 仅在每个状态都有自己的 ui-view 时才有效。一个 ui-view 应该事先声明。这是不可能的,因为理论上用户可以在我的应用程序中打开无限量的嵌套模式。
2。使用 UI-Router-Extras 方式使用自己的 built Modal windows
我尝试使用 UI-Router-Extras 的简单模态示例创建一个简单模态而不是 Angular UI 模态,如:http://plnkr.co/edit/qgt0RkEnXDPDTdMJPIfy?p=info
但不幸的是,我遇到了与选项 1 相同的问题。问题是当模态框嵌套时,状态和路由变得过于复杂。
解决方案
我现在真的很纠结什么是最好的方法。我正在考虑显示一个带有 iframe 的模态覆盖 window,它打开一个单独的 UI-Router 路由,例如:Modal.Customers.New,它只显示应用程序的内容(不是菜单酒吧等)。
使用 iframe 时,我可以在父 window 和 iframe 上保留单独的路线和状态信息。我需要执行一些自定义 javascript 以支持将 iframe 缩放为正确的格式,但这是可以接受的。
但它仍然感觉像是一个 "hacked" 解决方案。
我很想听听您的解决方案和见解。
最终我选择了将 iframe 与 Angular UI 模态框结合使用。这种方法让我可以完全灵活地在我的应用程序中使用复杂的路由,并且 Angular UI 的模态屏幕会在不同的屏幕分辨率下自动调整 iframe 的大小。
我已经为模式中使用的所有状态创建了路由,前缀为:modal。而不是应用程序。 这样,我只能使用页面的 "content" 子视图在 Modal 内部显示,并且仍然具有原始控制器和视图的完全可重用性。
唯一棘手的一点是打开多个嵌套模态框时。在那里我必须检查我是处于模式状态还是处于常规状态。使用州名称非常容易:
IsModal() {
return this.$state.current.name.indexOf("modal") == 0;
}
在根框架(非模态视图)上,我收集了数组中所有打开的 Angular UI 模态,如果模态位于视图(非模态)。如果没有,我使用以下方法将 iframe 向上遍历到父范围:
var parentScopeModalService = (<any>parent).angular.element(window.frameElement).scope().MyModalService;
这实际上非常有效,因为所有 iframe 都在同一个域中。