UI-Router中的嵌套状态提供了多个视图和范围继承



我有深嵌套的路由,比如

/customers
/customers/:customerId
/customers/:customerId/orders
/customers/:customerId/orders/:orderId

和,我有多个命名视图:一个标题,一个侧边栏和主要内容。

// customers.html
<div ui-view="header">
<div ui-view="sidebar">
<div ui-view="content">

我正试图得到一些要求一起工作:

  1. customer应该在/customers/:customerId下嵌套的所有路由中定义(即应该用定义customer的控制器创建作用域)
  2. 应该有一组默认的视图,用于嵌套在/customers/:customerId 下的所有路由,所有三个视图都应该可以访问父定义的customer

我可以实现的第一个要求:

$stateProvider
    .state("customers", {
        abstract: true,
        url: "/customers/:customerId",
        templateUrl: "customers.html",
        controller: "CustomersController as vm"
    })
    .state("customers.details", {
        url: "",
        views: {header: ..., sidebar: ..., content: ...}
    })
    .state("customers.orders", {
        url: "/orders",
        views: {header: ..., sidebar: ..., content: ...} // these have to be defined again
    })

注意customers.orders需要重新定义所有三个视图。这并不可怕,但我在想是否有更好的方法。我能想到的唯一方法是拥有另一个级别的状态,但这似乎更糟糕,因为状态名称包含一些与状态无关的东西,只是一个技术工件("默认"):

$stateProvider
    .state("customers", {
        // as above
    })
    .state("customers.default", {
        abstract: true,
        views: {header: ..., sidebar: ..., content: ...}
    })
    .state("customers.default.details", {
        url: "",
        views: {content: ...} // don't have to define all three views!
    })

请注意,在我的应用程序中,我不能翻转顺序并拥有app, app.customersapp.customers.details之类的东西,其中app提供三个默认视图,app.customers提供控制器。真正的应用程序有默认值,我想在路由的不同深度启动。

这是一个可能的解决方案。假设在根html文件中,有一个未命名的ui-view。假设这是您的customer.html文件:

<div ui-view="header">
<div ui-view="sidebar">
<div ui-view>
<div ui-view="content">

你的状态配置可以这样:

$stateProvider
    .state("customers", {
        abstract: true,
        url: "/customers/:customerId",
        views: {
            '': { // Populate root ui-view with customers.html
                templateUrl: "customers.html",
                controller: "CustomersController as vm"
            },
            'header@customers': { // Populate header ui-view in customers.html
                ...
            },
            'content@customers': {
                ...
            },
            'sidebar@customers': {
                ...
            }
        }
    })
    .state("customers.details", {
        url: "",
        views: {
            '@customers': { // Populate unnamed ui-view in customers.html
                ...
            }
        }
    })
    .state("customers.orders", {
        url: "/orders",
        views: {
            '@customers': {
                    ...
            }
        }
    })

这允许您让标题、侧边栏和内容ui视图对于客户状态的子元素保持不变。如果需要,子视图可以单独覆盖每个视图。因为所有这些视图都是嵌套的,所以它们可以像vm一样访问CustomersController。

最新更新