【问题标题】:How to efficiently architect the AngularUI ui-router state machine?如何有效地构建 AngularUI ui-router 状态机?
【发布时间】:2014-07-28 22:19:33
【问题描述】:

我对新的 AngularUI ui-router 库非常陌生,它允许我们使用状态机配置服务创建嵌套视图,并且正在尝试找出构建状态的最佳方法。我正在创建一个使用嵌套视图的应用程序,但我的实现与我看到的许多示例略有不同。

ui-router 演示展示了如何使用状态机语法{parent}.{child}.{grandchild} 实现嵌套视图,其中parent 可以具有等效路由/home/order/about 等。

现在让我们构建一个示例网站。假设在最顶层,我们有 3 个要渲染的视图。这 3 个视图是 /home/order/about。就ui-router 而言,所有这些视图基本上都是兄弟姐妹。但是,我们需要为应用程序的实际根提供一个抽象状态。这个状态我们称之为root

$stateProvider.
    .state('root', {
        abstract: true
        url: '/',
        templateUrl: 'templates/index.html`
    })

templates/index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <div ui-view></div>
</body>
</html>

现在由于root 是抽象的,我们不能直接转到/ 来查看我们的页面,我们必须调用子状态homeaboutorder 之一。让我们创建这些状态

$stateProvider
    .state('home', {
        url:'',
        templateUrl: 'templates/home.html'
    })
    .state('about', {
        url:'/about',
        templateUrl: 'templates/about.html'
    })
    .state('order', {
        url:'/order',
        templateUrl: 'templates/order.html'
    })

现在,如果我们导航到 //about/order,我们将分别路由到 homeaboutorder 状态。到目前为止,这似乎很简单,所以让我们再复杂一点。

homeabout 页面非常简单,不需要额外的工作,但是如果我们想让我们的 order 页面具有内部功能,例如 overview 页面、accounts 页面,该怎么办?和billings 页面。现在,导航到order 实际上会将我们带到overview,它将有一个导航菜单,然后在overview,accounts, andbillings` 之间移动。

要获得此功能,我们必须再次将order 抽象化。这样做允许我们只使用一个简单的ui-view 指令,该指令将用于渲染overviewaccountsbillings

templates/order.html

<ul id="navMenu">
        <li ui-sref-active="active"><a ui-sref="">Back</a></li>
        <li ui-sref-active="active"><a ui-sref=".overview">Overview</a></li>
        <li ui-sref-active="active"><a ui-sref=".accounts" >Accounts</a></li>
        <li ui-sref-active="active"><a ui-sref=".billing">Billing</a></li>
</ul>

<div ui-view></div>

现在我们的$stateProvider 将添加以下内容

$stateProvider
    .state('order', {
        abstract: true,
        url: '/order/:id',
        templateUrl: 'templates/order.html'
    })
    .state('order.overview', {
        url: '/overview',
        templateUrl: 'templates/order.overview.html'
    })
    .state('order.accounts', {
        url: '/accounts',
        templateUrl: 'templates/order.accounts.html'
    })
    .state('order.billing', {
        url: '/billing',
        templateUrl: 'templates/order.billing.html'
    })

请注意,order 状态是从之前修改的,因此现在它是抽象的,只能通过导航到其中一个子状态来访问。这是实际问题出现的地方。现在,我们的“状态”树看起来像

                          root (abstract)
                           / |  \
                          /  |   \
                         /   |    \
                        /    |     \
                     home  order  about
                           / |  \
                          /  |   \
                         /   |    \
                        /    |     \
                       /     |      \
                overview  accounts billing

一切看起来都很棒,但是现在可以说我们希望在accounts 下有另一个级别来查看帐户详细信息。我们希望accounts 页面有一个可以点击的帐户表。单击后,我们希望整个视图更改为帐户详细信息页面。此页面的 URL 从 accounts 转换到 account.details 看起来像

/order/:orderId/accounts OR /order/3/accounts

/order/:orderId/accounts/:accountId OR /order/3/accounts/71

这意味着使用帐户 ID 71 转到订单 3 并查看详细信息页面。然而在ui-router 中,accounts.details 视图实际上是accounts 的兄弟,因为我们希望整个视图切换到details,而不是accounts 内部的另一个嵌套视图。这样做的问题是我们不再遵循 ui-router 设计的状态层次结构。从概念的角度来看,帐户详细信息是 accounts 的子状态,但我们希望视图呈现为 AngularUI 状态视图,作为 accounts 的兄弟。

我正在尝试找出使用ui-router 提供的状态机设计来构建整个网站的正确方法。这意味着知道何时使用抽象状态,何时不使用。

有人能举例说明如何使用这些技术构建复杂网站吗?

【问题讨论】:

    标签: angularjs angular-ui angular-ui-router


    【解决方案1】:

    这里有几件事:

    本段暗示代码异味:

    这意味着转到帐户 ID 为 71 的订单 3 并查看详细信息页面。但是在 ui-router 中,accounts.details 视图实际上是帐户的兄弟,因为我们希望整个视图切换到详细信息,而不仅仅是帐户内部的另一个嵌套视图。这样做的问题是我们不再遵循 ui-router 设计的状态层次结构。从概念的角度来看,帐户详细信息是帐户的子状态,但我们希望视图呈现为 AngularUI 状态视图,作为帐户的兄弟。

    您的状态与您的观点不一致。一般来说,您应该确保是这种情况,并且我会尝试重新设计事物以便对齐。最好在您深入实施之前尽早执行此操作,因为随着时间的推移事情会变得更加复杂。你会发现自己在与状态机作斗争,而不是与它一起工作。

    现在,可能有一种方法可以在不对过渡进行任何更改的情况下获得您想要的内容。您遇到的问题不在于状态,而是当您转换到同级状态时,父状态的视图没有被刷新。您可以使用一些选项。请参阅ui-router $state 的文档。

    转换后您可能需要致电$state.reload。请注意不要陷入无限循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-26
      • 1970-01-01
      • 2014-12-11
      • 2014-12-16
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      相关资源
      最近更新 更多