Ui路由器:复合视图渲染一次视图

Ui Router: composite view render view once

我想要实现的是有 2 个同级视图,其中 1 个是 运行-一次,另一个将更新。

我有一个这样的模板:

<body>
    <ui-view="header />
    <ui-view="body" />
</body>

我有 1 个包罗万象的状态:

.state('root', {
    params: { … },
    resolve: {
        data: fn() { … }
    },
    url: '/{p1:string}/{p2:string}/{p3:string}',
    views: {
        header: {
            controller: 'HeaderCtrl as Header',
            templateUrl: '…'
        },
        body: {
            controllerProvider: fn() { … },
            templateUrl: fn() { … }
        }
    }
});

包罗万象的状态动态地选择合适的控制器、数据和模板。除了 HeaderCtrl 在每次状态更改时重新执行之外,一切都很顺利。我希望它只执行一次。

我尝试创建 2 个状态,rootbase,上面变成 root.base。我将 header 视图移动到新的 root 状态,如下所示:

.state('root', {
    abstract: true,
    url: '/',
    views: {
        header: {
            controller: 'HeaderCtrl as Header',
            templateUrl: '…'
        }
    }
})
.state('root.base', {
    params: { … },
    resolve: {
        data: fn() { … }
    },
    url: '/{p1:string}/{p2:string}/{p3:string}',
    views: {
        body: {
            controllerProvider: fn() { … },
            templateUrl: fn() { … }
        }
    }
});

但只有父 (root) 状态参与。

我创建了 working plunker here。你快到了。这是更新后的状态 def:

$stateProvider
  .state('root', {
    //abstract: true,
    //url: '/',
    views: {
        header: {
            controller: 'HeaderCtrl as Header',
            templateUrl: 'tpl.header.html',
        },
    }
})
.state('root.base', {
    params: { pl : null, p2: "", p3: "abc" },
    resolve: {
        data: function () { return  1 }
    },
    url: '/{p1:string}/{p2:string}/{p3:string}',
    views: {
        'body@': {
            controller: "MyCtrl",
            templateUrl: 'tpl.body.html',
        }
    }
});

首先,非常重要的是,我们必须对子状态视图名称使用绝对命名'body@'。参见:

View Names - Relative vs. Absolute Names

Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname@statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.

For example, the previous example could also be written as:

.state('report',{
    views: {
      'filters@': { },
      'tabledata@': { },
      'graph@': { }
    }
})

其次,未指定父级的 url...这将使 url 无法访问它。

此外,不需要抽象...可以...但是如果我们想使用 .when() 最好将其设为非抽象。检查这些:

  • Angular UI-Router $urlRouterProvider .when not working when I click <a ui-sref="...">
  • Angular UI-Router $urlRouterProvider .when not working *anymore*

使用上述内容的 plunker 是 here