我的应用程序有四种逻辑状态:
pages.list (lists pages)
pages.create (create a new page)
pages.item (show a single page)
pages.item.edit (edit a single page)
状态pages.list
和pages.item
共享一个基本模板(传统的三列布局),但状态pages.create
和pages.item.edit
具有完全不同的模板(完整页面编辑)。
用ui-router表达这个的最佳方法是什么?
答案 0 :(得分:5)
我想说使用abstract states
是可行的方法。在documentation中,他们清楚地概述了这些优点,其中一些非常适合您的用例(强调我的):
有关如何使用抽象状态的一些示例如下:
- 为所有子状态网址添加网址。
- 要插入一个模板,该模板具有自己的ui-view(s),其子状态将填充。
- (可选)将控制器分配给模板。控制器必须与模板配对。
- 此外,将$ scope对象继承到子级,只需了解这是通过视图层次结构而不是状态层次结构发生的。
- 通过解决方案提供已解决的依赖关系以供子状态使用。
- 通过子状态或事件监听器使用的数据提供继承的自定义数据。
- 运行可能以某种方式修改应用程序的onEnter或onExit函数。
- 上述任意组合。
根据这种理解,您的应用程序可以按如下方式构建:
创建两个页面可以使用的模板。我们称他们为three_columns.html
和one_column.html
。对于3列布局,请确保相应地命名ui-view
:
<!-- three_columns snippet -->
...
<body>
<div ui-view="left"></div>
<div ui-view="middle"></div>
<div ui-view="right"></div>
</body>
然后,单列模板:
<!-- one_column snippet -->
...
<body>
<div ui-view></div>
</body>
声明两个abstract states
。我们称他们为oneCol
和threeCols
。请注意,由于它们都声明了url: '/pages'
,因此所有继承的子状态都会自动将/pages
添加到自己的网址中。
$stateProvider
.state('oneCol', {
abstract: true,
url: '/pages',
templateUrl: 'layouts/one_column.html'
}).state('threeCols', {
abstract: true,
url: '/pages',
templateUrl: 'layouts/three_columns.html'
});
声明上述abstract states
延伸的州。假设我们称他们为list
,create
,view
和edit
。在此,threeCols.list
和threeCols.view
必须声明3 templateUrl
s,每个ui-view
一个。另一方面,oneCol.create
和oneCol.edit
会正常声明其未命名的templateUrl
。我通常使用的约定是创建一个特定于每个州的文件夹,因为它有利于组织子视图模板:
$stateProvider
.state('threeCols.list', {
url: '/list',
controller: 'ListCtrl',
views: {
'left': {
templateUrl: 'modules/list/leftbar.html'
},
'middle': {
templateUrl: 'modules/list/content.html'
},
'right': {
templateUrl: 'modules/list/rightbar.html'
}
}
}).state('oneCol.create', {
url: '/create',
controller: 'CreateCtrl',
templateUrl: 'modules/create/content.html'
}).state('threeCols.view', {
url: '/view',
controller: 'ViewCtrl',
views: {
'left': {
templateUrl: 'modules/view/leftbar.html'
},
'middle': {
templateUrl: 'modules/view/content.html'
},
'right': {
templateUrl: 'modules/view/rightbar.html'
}
}
}).state('oneCol.edit', {
url: '/edit',
controller: 'EditCtrl',
templateUrl: 'modules/edit/content.html'
});
有了这个,现在您的网址将如您所愿:/pages/list
,/pages/create
,/pages/view
,/pages/edit
。您也可以根据需要创建和重复使用模板。
答案 1 :(得分:0)
我通常根据视图定义我的路线,而不是真正基于模型。例如,鉴于上面的简单解释,我将使用以下内容:
$stateProvider
.state('pages.list', { url: '/list', controller: 'ListCtrl', templateUrl: 'threecol.html' })
.state('pages.create', { url: '/create', controller: 'CreateCtrl', templateUrl: 'create.html' })
.state('pages.item', { url: '/:itemId', controller: 'ItemCtrl', templateUrl: 'threecol.html' })
.state('pages.edit', { url: '/:itemId/edit', controller: 'EditCtrl', templateUrl: 'edit.html' });
基本上,您可以使用threecol.html
来定义常见的三列布局。 create.html
和edit.html
将是您的完整页面。
如果您想要围绕布局类型定义更抽象的方法,您还可以创建抽象父状态来定义布局本身。例如,您可以:
threecol.list
threecol.item
fullpage.create
fullpage.edit
如果您创建了threecol
和fullpage
抽象状态,则可以定义常用的布局标记,并在需要的位置插入适当的<div ui-view=""></div>
。这样,您可以为list
和item
使用不同的内容模板文件。