AngularUI Router: несколько состояний с одинаковым шаблоном URL
Привет всем, что я натолкнулся на то, что, как я думал, будет общей проблемой маршрутизации, но я не могу найти решение. В основном моя страница имеет два состояния, базовые и расширенные, и я хочу, чтобы шаблоны URL были одинаковыми для обоих состояний, но загружали только шаблон для текущего состояния (который переводится изнутри контроллера).
config(function ($stateProvider) {
$stateProvider.state('basic', {
url: '/:post',
templateUrl: function (stateParams) {
return 'post-' + stateParams.post + '-tmpl.html';
}
});
$stateProvider.state('advanced', {
url: '/:post',
templateUrl: function (stateParams) {
return 'post-' + stateParams.post + '-advanced-tmpl.html';
}
});
})
controller('myCtrl', function ($state) {
//
// In this case, I would expect only the template from
// the advanced state to load, but both templates are trying
// to load.
$state.transitionTo('advanced', {post: 2});
}
Я предполагаю, что переход к совпадающему шаблону загружает заданное состояние, поэтому, когда он совпадает, оба шаблона пытаются загрузить. Есть ли способ выполнить один и тот же шаблон url, но с разными шаблонами, основанными только на текущем состоянии?
Ответы
Ответ 1
Предполагая, что вы не можете иметь два состояния с одним и тем же URL-адресом, почему бы вам не пойти и объединить два состояния в один? Ui-router уже позволяет вам иметь настраиваемую функцию для возврата шаблона. Вам просто нужно добавить еще один скрытый настраиваемый параметр (позвоните ему advanced
) в декларацию состояния:
$stateProvider.state('basicOrAdvanced', {
url: '/:post',
templateUrl: function (stateParams) {
if (stateParams.advanced) {
return 'post-' + stateParams.post + '-advanced-tmpl.html';
} else {
return 'post-' + stateParams.post + '-tmpl.html';
}
},
params: {
advanced: False
}
});
И затем вы вызываете его с помощью:
$state.transitionTo('basicOrAdvanced', {post: 2, advanced: True})
Для другого возможного решения с вложенными состояниями и общим контроллером см. проблемы # 217 и # 1096 на странице uit-router github.
Представленное там решение создает третье состояние, контроллер которого выполняет диспетчерскую работу, тогда как два состояния, в которые вы хотите приземлиться (basic
и advanced
), имеют пустые URL-адреса:
$stateProvider.state('basicOrAdvanced', {
url: '/:post',
controller: function($state, $stateParams) {
if($stateParams.advanced) {
$state.go('advanced', {post: $stateParams.post});
} else {
$state.go('basic', {post: $stateParams.post});
}
},
params: {
advanced: False
}
}
Это решение лучше, если ваши состояния отличаются друг от друга по сравнению с простым templateUrl
(например, если у них есть полностью отдельные контроллеры и т.д.)
Также см. fooobar.com/questions/195179/....
Ответ 2
Это очень полезно в AngularJS,
Вы можете указать Динамический маршрут для нескольких состояний с одинаковым шаблоном URL
Мой код Как следует, это может быть полезно для вас,
Интеллизация модуля,
var app = angular.module("koops_app", ['ui.router','ui.bootstrap']); //here you have to define all your required module for your project that you should inject...
Далее
app.config(function ($locationProvider, $httpProvider, $stateProvider, $urlRouterProvider, $wampProvider) {
// When No Routing i.e Default Routing
$urlRouterProvider.when('', '/dashboard');
// 404
$stateProvider.state("404", {
url: "/404",
templateUrl: 'template/404.html',
});
// When Only One Argument i.e. Only Module Name
$stateProvider.state("default", {
url: "/:section",
templateUrl: 'views/View-to-be-load.html', //can use $stateParams.section for dynamic
reload: true,
resolve: {
loadController: ['$q', '$stateParams', '$state',
function ($q, $stateParams, $state) {
var deferred = $q.defer();
deferred.resolve();
return deferred.promise;
}
]
},
controllerProvider: function ($stateParams) {
return 'controllerName';
}
});
// When Two Argument i.e. Module/Controller
$stateProvider.state("default/title", {
url: "/:section/:title",
templateUrl: 'views/View-to-be-load.html', //can use $stateParams.section for dynamic
reload: true,
resolve: {
loadController: ['$q', '$stateParams', '$state',
function ($q, $stateParams, $state) {
var deferred = $q.defer();
deferred.resolve();
return deferred.promise;
}
]
},
controllerProvider: function ($stateParams) {
return 'controllerName';
}
});
// When Three Arguments i.e. Module/Controller/id
$stateProvider.state("default/title/id", {
url: "/:section/:title/:id",
templateUrl: 'views/View-to-be-load.html', //can use $stateParams.section for dynamic
reload: true,
resolve: {
loadController: ['$q', '$stateParams', '$state',
function ($q, $stateParams, $state) {
var deferred = $q.defer();
deferred.resolve();
return deferred.promise;
}
]
},
controllerProvider: function ($stateParams) {
return 'controllerName';
}
});
// Otherwise
$urlRouterProvider.otherwise("/404");
Может быть, это полезно для вас...
Наслаждайтесь...
Ответ 3
Вам нужно использовать вложенные состояния
config(function ($stateProvider) {
$stateProvider.state('post', {
url: '/:post',
templateUrl: function (stateParams) {
return 'post-' + stateParams.post + '-advanced-tmpl.html';
}
});
$stateProvider.state('post.basic', {
url: '/:post',
templateUrl: function (stateParams) {
return 'post-' + stateParams.post + '-tmpl.html';
}
});
})
controller('myCtrl', function ($state, $timeout) {
// go to advanced
$state.transitionTo('post', {post: 2});
// after 500ms switch to basic
$timeout(function() {
$state.transitionTo('post.basic', {post: 2});
}, 500)
}
Ответ 4
Почему вы хотите иметь два разных вида, сопоставленных с одним и тем же URL. Представляете ли вы проблему, когда пользователь захочет добавить закладку в одно из состояний? Как бы вы тогда узнали, кто из них, если у них точно такой же URL?
Я бы предложил определить два разных состояния, например:
- /: post - для простого представления
- /: post/advanced - для расширенного представления
Это можно сделать с определением /: post как абстрактного состояния и двух разных состояний для простого и расширенного представления. Для удобства простое представление будет действовать как значение по умолчанию. Если вам нравится идея, я могу предоставить вам пример решения.
Другой вариант - добавить параметр url, например:
- /: post - для простого представления
- /: запись вид = расширенный
Я надеюсь, что этот ответ поможет вам. По крайней мере, видя вещи с разных сторон;).