使用 Ui-Router 在 AngularJS 中设置动态 URL 状态
Set dynamic URL on state in AngularJS with Ui-Router
我的页面上有一个 ng-include 呈现部分,但由于 ng-include 的性质,我不需要状态来加载部分。我希望 URL 在 ng-include 更新其视图时更新,以便我的分析将其跟踪为页面更改。我想知道最好的方法。
我也在使用 angular-ui-router,这使得 ng-include 由于嵌套状态而变得无关紧要;直到有人遇到我的情况:我有大量的部分加载到 ng-include 中,这很可爱,因为我需要提供的只是部分的路径,而不是我的 $stateProvider 文件的大量不同状态;但是没有自定义url。因此,我想知道的是:
Ng-include 是否可以在加载局部视图时更新页面 url 而没有为该局部视图定义状态
或
可以完全解决我的问题的东西: 有没有办法添加具有 url 的状态,可以动态更新?喜欢:
.state( 'test', {
url: function( stateId ){
// where stateId is somehow passed into the $stateParams of the new state
},
templateUrl: "templates/views/test.html"
})
这是我的 ng-include 到目前为止的设置,如果您对如何在 ng-include 呈现不同部分时更改 url 有任何想法,我会非常高兴。
::JS::
// states
// self executing function
(function() {
var app = angular.module( 'app', [ 'ui.router', 'ngAnimate' ] );
app.config( function( $stateProvider, $urlRouterProvider ) {
// if url not defined redirect to login
$urlRouterProvider.when( '', "/home" );
// if nonexistant url defined redirect to sign-in
$urlRouterProvider.otherwise( "/home" );
// Now set up the states
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/views/home.html"
});
}()); // self executing function end
// factory
//self executing container function
(function() {
var listFactory = function( ) {
// declare factory for return at end of function
var factory = {};
var list =
{
list1 : [
{
name: 'first',
url: 'templates/views/partials/view1.html',
id: '1'
},
{
name: 'second',
url: 'templates/views/partials/view2.html',
id: '2'
},
{
name: 'third',
url: 'templates/views/partials/view3.html',
id: '3'
},
{
name: 'fourth',
url: 'templates/views/partials/view4.html',
id: '4'
}
]
};
factory.getList = function(){
return list;
};
// return factory object to access data
return factory;
};
angular.module( 'app' ).factory( 'listFactory', listFactory );
}());
// controller
//self executing container function
(function() {
var listController = function ( $scope, listFactory ) {
$scope.listFactory = listFactory.getList();
// set a default list state
$scope.currentList = 'templates/views/partials/default.html';
// function sets list url on click to new scope item for rendering partial view
$scope.setCurrentList = function( url ) {
$scope.currentList = url;
};
};
listController.$inject = [ '$scope', 'listFactory' ];
angular.module('app')
.controller('listController', listController);
}());
::HTML::
<!-- this is loaded in the home state. -->
<div>
<div id="{{ list.id }}" ng-repeat="list in list.list1" ng-click="setCurrentList( list.url )">
<p>{{ list.name }}</p>
</div>
</div>
<div id="list-view-container">
<div class="rotateViewAnimate" ng-include src="currentList"></div>
</div>
::相当不相关 CSS::
/* Have to set height explicity on ui-view-container
to prevent collapsing during animation*/
#list-view-container {
position: relative;
min-height: 500px;
overflow: hidden;
}
/* rotate in / out animation transition */
.rotateViewAnimate.ng-enter, .rotateViewAnimate.ng-leave {
/* settings so animations display together */
position: absolute!important;
left: 0!important;
right: 0!important;
-webkit-transition: 0.5s ease-in-out all;
-moz-transition: 0.5s ease-in-out all;
-o-transition: 0.5s ease-in-out all;
transition: 0.5s ease-in-out all;
transform-style: preserve-3d;
}
.rotateViewAnimate.ng-enter {
transform: rotateY(90deg);
opacity: 0;
}
.rotateViewAnimate.ng-enter-active {
transform: rotateY(0deg);
opacity:1;
}
.rotateViewAnimate.ng-leave {
transform: rotateY(0deg);
opacity:1;
}
.rotateViewAnimate.ng-leave-active {
transform: rotateY(90deg);
opacity:0;
}
好的,所以对于使用 Ui-Router 的部分,您需要包含一个
<ui-view>
<i>Some content will load here!</i>
</ui-view>
您希望部分加载的位置。
看起来你的家庭状态工作正常,但如果你想嵌套视图你必须做这样的事情
.state('home.view1', {
url: '/notes',
templateUrl: 'pages/view1.html',
controller: 'mainController'
})
执行此嵌套路由的完整 Url 将是 */#/home/notes
欲了解更多信息:
https://github.com/angular-ui/ui-router/wiki
已解决
ui-router 文档中详细介绍了我要解决的问题;在这里找到:
https://github.com/angular-ui/ui-router/wiki
我使用了下面的方法来达到这里所说的效果:
"Set a Dynamic URL on a state using ui-router and angularJS"
查看问题中显示的代码,我将根据我的解决方案对其进行相应调整。
// states
// self executing function
(function() {
var app = angular.module( 'app', [ 'ui.router', 'ngAnimate' ] );
app.config( function( $stateProvider, $urlRouterProvider ) {
// if url not defined redirect to login
$urlRouterProvider.when( '', "/home" );
// if nonexistant url defined redirect to sign-in
$urlRouterProvider.otherwise( "/home" );
// Now set up the states
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/views/home.html"
})
.state( 'home.urlChanger', {
url: '/urlChanger/name=:name&url=:url',
params: {
'spareParam' : 'whateverString'
},
views: {
'viewName@home': {
templateUrl: function ( $stateParams ){
return $stateParams.url;
},
controller: "mainController"
}
}
});
}()); // self executing function end
在上面的状态声明中,状态 "home.urlChanger" 有一个带有特殊字符的 url,这些字符的值来自传递给 $stateProvider 变量的信息。这里有一个非常重要的注意事项是,如果想要访问存储在 $stateParams 中的项目,则必须将其传递到 URL 中。因此,在我的控制器中,我使用以下函数通过 $state.go(); 传递我希望在状态下可用的信息;方法如下:
$scope.setParams = function( location ) {
var urlname = object.stored.in.factory.NAME,
url = object.from.factory.URL, // path to html file passed to be used in termplateurl from state
// set stateParams.name to be used in URL
$stateParams.name = urlName;
// set params to be passed into URL when $state.go(); is called, they will be available for use then and update the URL with the state setup from above.
$state.go( location, { name: $stateParams.name, url: url } );
};
从上面的示例可以看出,我尝试将其存储到 $stateparams.name 中以查看它是否会在状态参数中可用,但正如预期的那样 state.go();被称为一个新的状态被加载并且之前的 $stateparams 对象不再可用。因此,为什么必须在 $state.go 期间传递信息,以便将其存储到新转换的状态 $stateParams 对象中。
所以导致这种情况发生的 html 可能是对调用 setparams( location ) 函数的任何元素的 ng-click,这将通过将变量传递给 URL 并使它们在您所在的州可用,即:由州本身设置的动态 URL。
希望有人发现这有点帮助,我花了一些时间来完成自己的工作。
案例是在 http 创建请求 (201) 之后更改页面 URL
这是一个例子:
StudentsService.create($stateParams.sudId,studentInfo).then(r => {
$scope.newStudentId=r.data.id;
console.log(r.data, $scope.newStudentId);
$state.go("stateName", {sudId:$stateParams.sudId, id:$scope.newStudentId});
所以,创建后会发给新生url。
我的页面上有一个 ng-include 呈现部分,但由于 ng-include 的性质,我不需要状态来加载部分。我希望 URL 在 ng-include 更新其视图时更新,以便我的分析将其跟踪为页面更改。我想知道最好的方法。
我也在使用 angular-ui-router,这使得 ng-include 由于嵌套状态而变得无关紧要;直到有人遇到我的情况:我有大量的部分加载到 ng-include 中,这很可爱,因为我需要提供的只是部分的路径,而不是我的 $stateProvider 文件的大量不同状态;但是没有自定义url。因此,我想知道的是:
Ng-include 是否可以在加载局部视图时更新页面 url 而没有为该局部视图定义状态
或
可以完全解决我的问题的东西: 有没有办法添加具有 url 的状态,可以动态更新?喜欢:
.state( 'test', {
url: function( stateId ){
// where stateId is somehow passed into the $stateParams of the new state
},
templateUrl: "templates/views/test.html"
})
这是我的 ng-include 到目前为止的设置,如果您对如何在 ng-include 呈现不同部分时更改 url 有任何想法,我会非常高兴。
::JS::
// states
// self executing function
(function() {
var app = angular.module( 'app', [ 'ui.router', 'ngAnimate' ] );
app.config( function( $stateProvider, $urlRouterProvider ) {
// if url not defined redirect to login
$urlRouterProvider.when( '', "/home" );
// if nonexistant url defined redirect to sign-in
$urlRouterProvider.otherwise( "/home" );
// Now set up the states
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/views/home.html"
});
}()); // self executing function end
// factory
//self executing container function
(function() {
var listFactory = function( ) {
// declare factory for return at end of function
var factory = {};
var list =
{
list1 : [
{
name: 'first',
url: 'templates/views/partials/view1.html',
id: '1'
},
{
name: 'second',
url: 'templates/views/partials/view2.html',
id: '2'
},
{
name: 'third',
url: 'templates/views/partials/view3.html',
id: '3'
},
{
name: 'fourth',
url: 'templates/views/partials/view4.html',
id: '4'
}
]
};
factory.getList = function(){
return list;
};
// return factory object to access data
return factory;
};
angular.module( 'app' ).factory( 'listFactory', listFactory );
}());
// controller
//self executing container function
(function() {
var listController = function ( $scope, listFactory ) {
$scope.listFactory = listFactory.getList();
// set a default list state
$scope.currentList = 'templates/views/partials/default.html';
// function sets list url on click to new scope item for rendering partial view
$scope.setCurrentList = function( url ) {
$scope.currentList = url;
};
};
listController.$inject = [ '$scope', 'listFactory' ];
angular.module('app')
.controller('listController', listController);
}());
::HTML::
<!-- this is loaded in the home state. -->
<div>
<div id="{{ list.id }}" ng-repeat="list in list.list1" ng-click="setCurrentList( list.url )">
<p>{{ list.name }}</p>
</div>
</div>
<div id="list-view-container">
<div class="rotateViewAnimate" ng-include src="currentList"></div>
</div>
::相当不相关 CSS::
/* Have to set height explicity on ui-view-container
to prevent collapsing during animation*/
#list-view-container {
position: relative;
min-height: 500px;
overflow: hidden;
}
/* rotate in / out animation transition */
.rotateViewAnimate.ng-enter, .rotateViewAnimate.ng-leave {
/* settings so animations display together */
position: absolute!important;
left: 0!important;
right: 0!important;
-webkit-transition: 0.5s ease-in-out all;
-moz-transition: 0.5s ease-in-out all;
-o-transition: 0.5s ease-in-out all;
transition: 0.5s ease-in-out all;
transform-style: preserve-3d;
}
.rotateViewAnimate.ng-enter {
transform: rotateY(90deg);
opacity: 0;
}
.rotateViewAnimate.ng-enter-active {
transform: rotateY(0deg);
opacity:1;
}
.rotateViewAnimate.ng-leave {
transform: rotateY(0deg);
opacity:1;
}
.rotateViewAnimate.ng-leave-active {
transform: rotateY(90deg);
opacity:0;
}
好的,所以对于使用 Ui-Router 的部分,您需要包含一个
<ui-view>
<i>Some content will load here!</i>
</ui-view>
您希望部分加载的位置。
看起来你的家庭状态工作正常,但如果你想嵌套视图你必须做这样的事情
.state('home.view1', {
url: '/notes',
templateUrl: 'pages/view1.html',
controller: 'mainController'
})
执行此嵌套路由的完整 Url 将是 */#/home/notes 欲了解更多信息: https://github.com/angular-ui/ui-router/wiki
已解决
ui-router 文档中详细介绍了我要解决的问题;在这里找到:
https://github.com/angular-ui/ui-router/wiki
我使用了下面的方法来达到这里所说的效果:
"Set a Dynamic URL on a state using ui-router and angularJS"
查看问题中显示的代码,我将根据我的解决方案对其进行相应调整。
// states
// self executing function
(function() {
var app = angular.module( 'app', [ 'ui.router', 'ngAnimate' ] );
app.config( function( $stateProvider, $urlRouterProvider ) {
// if url not defined redirect to login
$urlRouterProvider.when( '', "/home" );
// if nonexistant url defined redirect to sign-in
$urlRouterProvider.otherwise( "/home" );
// Now set up the states
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/views/home.html"
})
.state( 'home.urlChanger', {
url: '/urlChanger/name=:name&url=:url',
params: {
'spareParam' : 'whateverString'
},
views: {
'viewName@home': {
templateUrl: function ( $stateParams ){
return $stateParams.url;
},
controller: "mainController"
}
}
});
}()); // self executing function end
在上面的状态声明中,状态 "home.urlChanger" 有一个带有特殊字符的 url,这些字符的值来自传递给 $stateProvider 变量的信息。这里有一个非常重要的注意事项是,如果想要访问存储在 $stateParams 中的项目,则必须将其传递到 URL 中。因此,在我的控制器中,我使用以下函数通过 $state.go(); 传递我希望在状态下可用的信息;方法如下:
$scope.setParams = function( location ) {
var urlname = object.stored.in.factory.NAME,
url = object.from.factory.URL, // path to html file passed to be used in termplateurl from state
// set stateParams.name to be used in URL
$stateParams.name = urlName;
// set params to be passed into URL when $state.go(); is called, they will be available for use then and update the URL with the state setup from above.
$state.go( location, { name: $stateParams.name, url: url } );
};
从上面的示例可以看出,我尝试将其存储到 $stateparams.name 中以查看它是否会在状态参数中可用,但正如预期的那样 state.go();被称为一个新的状态被加载并且之前的 $stateparams 对象不再可用。因此,为什么必须在 $state.go 期间传递信息,以便将其存储到新转换的状态 $stateParams 对象中。
所以导致这种情况发生的 html 可能是对调用 setparams( location ) 函数的任何元素的 ng-click,这将通过将变量传递给 URL 并使它们在您所在的州可用,即:由州本身设置的动态 URL。
希望有人发现这有点帮助,我花了一些时间来完成自己的工作。
案例是在 http 创建请求 (201) 之后更改页面 URL 这是一个例子:
StudentsService.create($stateParams.sudId,studentInfo).then(r => {
$scope.newStudentId=r.data.id;
console.log(r.data, $scope.newStudentId);
$state.go("stateName", {sudId:$stateParams.sudId, id:$scope.newStudentId});
所以,创建后会发给新生url。