构建多步骤表单(“向导”)。最初是this tutorial,它工作得很好,但我现在正在尝试调整它,因此第一步嵌入在主页上,而不是一个单独的状态。无论我尝试什么,我都无法创建一个可行的ui-sref
路径。我总是得到:
无法解决州'home'的'.where'
或
无法从州'home'
解析'wizard.where'
或
无法从州'home'
解析'wizard.where @'
...即使wizard.where@
在<div ui-view="wizard.where@"></div>
中正常工作。什么是正确的语法?
以下是相关文件:
home.js (左边的评论完好无损,所以你可以看到我正在尝试的各种方法):
var wizard = {
url: '/home/wizard',
controller: 'VendorsCtrl',
templateUrl: 'vendors/wizard.tpl.html'
};
angular.module( 'myApp.home', [
'ui.router',
'ui.bootstrap',
'myApp.modal',
'angularMoment'
])
.config(function config( $stateProvider, $urlRouterProvider ) {
$stateProvider
.state( 'home', {
url: '/home',
views: {
"main": {
controller: 'HomeCtrl',
templateUrl: 'home/home.tpl.html'
},
"jumbotron": {
controller: 'HomeCtrl',
templateUrl: 'home/welcome.tpl.html'
},
"wizard": wizard,
"wizard.where": {
url: '/home/wizard/where',
controller: 'VendorsCtrl',
templateUrl: 'vendors/wizard-where.tpl.html',
parent: wizard
},
"wizard.what": {
url: '/home/wizard/what',
controller: 'VendorsCtrl',
templateUrl: 'vendors/wizard-what.tpl.html',
parent: wizard
},
"wizard.when": {
url: '/home/wizard/when',
controller: 'VendorsCtrl',
templateUrl: 'vendors/wizard-when.tpl.html',
parent: wizard
},
},
data: { pageTitle: 'Home' }
})
// route to show our basic form (/wizard)
// .state('wizard', {
// url: '/wizard',
// views: {
// "main": {
// controller: 'VendorsCtrl',
// templateUrl: 'vendors/wizard.tpl.html'
// }
// },
// abstract: true,
// //data: { pageTitle: 'Vendor Search' }
// })
// nested states
// each of these sections will have their own view
// url will be nested (/wizard/where)
// .state('wizard.where', {
// url: '/where',
// templateUrl: 'vendors/wizard-where.tpl.html'
// })
// url will be /wizard/when
// .state('wizard.when', {
// url: '/when',
// templateUrl: 'vendors/wizard-when.tpl.html'
// })
// url will be /wizard/vendor-types
// .state('wizard.what', {
// url: '/what',
// templateUrl: 'vendors/wizard-what.tpl.html'
// })
;
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/home/wizard/where');
})
wizard.tpl.html :
<div class="jumbotron vendate-wizard" ng-controller="VendorsCtrl as vendorsCtrl">
<header class="page-title">
<h1>{{ pageTitle }}</h1>
<p>Answer the following three questions to search available vendors. All answers can be changed later.</p>
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref="wizard.where@"><span>1</span> Where</a>
<a ui-sref-active="active" ui-sref="wizard.what@"><span>2</span> What</a>
<a ui-sref-active="active" ui-sref="wizard.when@"><span>3</span> When</a>
</div>
</header>
<!-- use ng-submit to catch the form submission and use our Angular function -->
<form id="signup-form" ng-submit="processForm()">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view="wizard.where@"></div>
</form>
</div>
wizard.where.tpl.html :
<div class="form-group">
<label class="h2" for="where">Where Is Your Wedding?</label>
<p id="vendor-where-description">If left blank, vendors in all available locations will be shown.</p>
<div class="input-group-lg">
<input id="where" ng-model="formData.where" class="form-control" type="text" placeholder="Boston, MA" aria-describedby="vendor-where-description" />
</div>
</div>
<ul class="list-inline">
<li>
<a ui-sref="wizard.what@" class="btn btn-block btn-primary">
Next <span class="fa fa-arrow-right"></span>
</a>
</li>
</ul>
答案 0 :(得分:42)
注意:您应该阅读有关状态嵌套和命名视图的更多信息。因为当前的状态和视图定义完全错误。
首先,我们不应该将 ONE 状态定义与许多 views: {}
一起使用。但我们应该把它们分成现实状态。层次结构将具有三个级别
第一级 - 超级根状态
.state( 'home', {
url: '/home',
views: {
"main": {
controller: 'HomeCtrl',
templateUrl: 'home/home.tpl.html'
},
}
})
第二级 - wizzard,检查现在我们是否更改了网址。我们将从父(home)继承其第一部分
.state("wizard", {
parent: 'home',
//url: '/home/wizard',
url: '/wizard',
controller: 'VendorsCtrl',
templateUrl: 'vendors/wizard.tpl.html'
})
第三级 - 所有where,what,when现在还将继承url。他们不必定义父,因为它是他们名字的一部分
.state( "wizard.where", {
//url: '/home/wizard/where',
url: '/where',
controller: 'VendorsCtrl',
templateUrl: 'vendors/wizard-where.tpl.html',
//parent: wizard
})
.state( "wizard.what", {
//url: '/home/wizard/what',
url: '/what',
controller: 'VendorsCtrl',
templateUrl: 'vendors/wizard-what.tpl.html',
//parent: wizard
})
.state( "wizard.when", {
//url: '/home/wizard/when',
url: '/when',
controller: 'VendorsCtrl',
templateUrl: 'vendors/wizard-when.tpl.html',
//parent: wizard
})
父 wizzard 现在必须包含未命名的视图目标 ui-view=""
<div ui-view=""></div>
目前 wizard.tpl.html 包含以下内容:
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view="wizard.where@"></div>
应该避免使用符号 @
,因为它可以用于绝对视图命名 - 但是在状态定义内部。那么,可行的是 ui-view="someName
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view="someName"></div>
现在,这些是 home.tpl
<div>
<h1>HOME</h1>
<div ui-view=""></div>
</div>
wizzard.tpl
<div>
<h2>WIZZARD</h2>
<div ui-view=""></div>
</div>
因此,我们在主页和向导状态中有未命名的视图目标,这非常方便,因为我们可以使用灯光状态定义,而不需要 { {1}} 对象。如果我们没有多视图,那总是首选。
这意味着,这个状态定义将正确地注入到上面的模板中:
views : {}
检查文档:
在幕后,为每个视图分配一个遵循
// no views - search in parent for a ui-view="" ... .state( "wizard.when", { url: '/when', controller: 'VendorsCtrl', templateUrl: 'vendors/wizard-when.tpl.html', }) ...
方案的绝对名称,其中viewname是视图指令中使用的名称,州名是州的绝对名称,例如contact.item。您还可以选择以绝对语法编写视图名称。例如,前面的例子也可以写成:
viewname@statename
请注意,视图名称现在指定为绝对名称,而不是相对名称。它定位于根未命名模板中的“过滤器”,“tabledata”和“图表”视图。由于它没有命名,因此'@'后面没有任何内容。根未命名的模板是您的index.html。
从州调用州
我们想要在状态导航到何时,我们可以使用directiv .state('report',{
views: {
'filters@': { },
'tabledata@': { },
'graph@': { }
}
})
,但它必须包含州名,而不是视图命名约定
ui-sref
原因是,在这个三级层次结构中,我们只使用父名和子名(不是祖父'home'),隐藏在状态定义中。因为我们使用了这个:
// instead of this
<a ui-sref="wizard.what@"
we need this
<a ui-sref="wizard.what"
父只是父母,不是州名的一部分。在像这样的场景中哪个好(我们需要root / grand parent来建立一些comon的东西,但子站点不需要它的名字)
检查文档:
将链接(
.state("wizard", { parent: 'home',
标记)绑定到状态的指令。如果状态具有关联的URL,则该指令将自动生成&amp;通过 $ state.href()方法更新href属性。单击该链接将触发带有可选参数的状态转换 ...您可以使用
<a>
属性指定要传递给 $ state.go()的选项。选项仅限于位置,继承和重新加载。
ui-sref-opts
- 字符串 - 'stateName'可以是任何有效的绝对或相对状态
答案 1 :(得分:3)
[S] tep one嵌入在主页上而不是单独的状态
您应该将每个ui视图视为一种状态,但将wizard.where
声明为default/index state。
请注意,本教程使用$ urlRouterProvider使form/profile
成为默认状态。
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/form/profile');
但是,以这种方式,/form
将最终为/form/profile
。
但是,您可以使用minor modification创建一个空的URL状态:
// route to show our basic form (/form)
.state('form', {
url: '/form',
templateUrl: 'form.html',
controller: 'formController',
abstract: true //<-- Declare parent as an abstract state.
})
// nested states
// each of these sections will have their own view
// url will be nested (/form)
.state('form.profile', {
url: '', //<-- Empty string for "profile" state to override the /form abstract state
templateUrl: 'form-profile.html'
})
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/form'); //<-- Default state is empty
@ radim-köhler还提供了对UI路由器和状态定义的深入了解。