角度模态(ui-router)和一般模态架构概念

时间:2016-04-25 15:15:33

标签: angularjs modal-dialog angular-ui-router angular-ui-router-extras

我正在开发一个相当复杂的AngularJS Web应用程序,并且无法实现符合我要求的工作模式/路由机制。

场合

我的应用程序已经(简化)了以下实体:

  • 客户(拥有0个或更多联系人)
  • 订单(只有1位客户)
  • 联系人(仅属于1位客户)

在创建新订单期间,可以选择现有客户,也可以创建新客户。在客户的创建过程中,可以选择创建新的联系人。

UI / UX解决方案

我已经研究了几种以“非杂乱”和移动友好的方式正确表示此功能的方法。首先,我试图完全远离模态或弹出窗口并尝试创建几个Angular指令以在页面中动态显示,但这很快就变得太复杂了。创建新客户存在多个UI状态和一些子状态(选项卡),并且其中包含相当复杂的逻辑。

然后我查看了使用单独的浏览器选项卡,并使用localStorage在它们之间进行通信。然而,这种方法似乎很脆弱,对用户来说也不常见。此外,用户应该继续使用新选项卡直到完成,然后才能返回上一个选项卡。使用单独的浏览器选项卡是不可能的。

我看过Javascript浏览器弹出窗口,但我也不喜欢这个方向。

从用户的角度来看,我认为最好的方法是使用模态对话框来跟踪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     |
      +----<-----<-------<-----<---+   +----<-----<-------<-----<----+

注意:新客户和新联系人状态本身也是状态,可以在常规窗口中打开。

我创建了Angular-UI-Router路由:

  • 新订单:app.orders.new
  • 新客户:app.customers.new
  • 新联系人:app.contacts.new

开发

为了支持多模态架构,我尝试了几件事:

  1. 使用Angular UI Bootstrap Modal
  2. 使用自己构建的模态窗口{/ 3}}方式
  3. 要记住的一些重要方面:

    • 我不需要直接URL直接指向模态窗口。该URL可以保留在“新客户”状态。
    • 行为应为Modal,因此无法在父窗口上运行。
    • 它应该能够打开并在彼此之后显示多个状态(例如,一个模态中的向导)
    • 按特定顺序打开的多个模式应按相同的顺序关闭。 (最后,先出)

    1。使用UI-Router-Extras 这样看起来很有希望。我创建了一个单独的路由,它使用常规路由的一些控制器和视图:

    • Modal.Customers.New
    • Modal.Contacts.New

    但不幸的是,我很难在模态中打开更多模态并保持前一模态的状态。我使用了UI-Router-Extras Sticky States来保持背景状态。然而,正如UI-Router-Extras所述,Sticky States仅在每个州拥有自己的ui-view时才有效。应事先声明ui-view。这是不可能的,因为理论上用户可以在我的应用程序中打开无限量的嵌套模态。

    2。使用自己构建的模态窗口{/ 3}}方式

    我尝试使用UI-Router-Extras的简单模态示例创建一个简单的模态而不是Angular UI模式,如:Angular UI Bootstrap Modal

    但不幸的是,我遇到与选项1相同的问题。问题是状态和路由在嵌套模态时变得太复杂。

    解决方案

    我真的在努力解决现在最好的方法。我正在考虑显示一个带有iframe的模态覆盖窗口,它打开一个单独的UI-Router路由,如:Modal.Customers.New,它只显示应用程序的内容(不是菜单栏等)。

    使用iframe时,我可以在父窗口和iframe上保留单独的路径和状态信息。我需要执行一些自定义JavaScript以支持将iframe缩放到正确的格式,但这是可以接受的。

    但它仍然感觉像是一个“黑客”解决方案。

    我很想听听您的解决方案和见解。

1 个答案:

答案 0 :(得分:0)

最终我选择了使用iframe和Angular UI Modals的组合。这种方法让我在我的应用程序中使用复杂路径时具有完全的灵活性,Angular UI的Modal屏幕会自动调整不同屏幕分辨率的iframe大小。

我已经为Modals中使用的所有状态创建了路径:modal。而不是应用程序。 这样我只能使用页面的“内容”子视图显示在Modal内部,并且仍然具有原始控制器和视图的完全可重用性。

唯一棘手的一点是打开多个嵌套的Modals时。在那里,我必须检查我是否处于模态或常规状态。使用州名称非常容易:

IsModal() {
    return this.$state.current.name.indexOf("modal") == 0;
}

在根框架(非模态视图)上,我收集了数组中所有打开的Angular UI Modals,并检查了如果Modal位于视图的根部(非模态),则打开一个新模态。如果没有,我使用以下方法遍历iframe到父作用域:

var parentScopeModalService = (<any>parent).angular.element(window.frameElement).scope().MyModalService;

这实际上非常好用,因为所有的iframe都在同一个域上。