Об этом уже спрашивали, и из ответов это выглядит не очень хорошо. Я хотел бы спросить с этим примером кода в рассмотрении ...
Мое приложение загружает текущий элемент в сервисе, который его предоставляет. Существует несколько контроллеров, которые управляют данными элемента без перезагрузки элемента.
Мои контроллеры перезагрузят элемент, если он еще не установлен, в противном случае он будет использовать текущий загруженный элемент из службы, между контроллерами.
Проблема : я хотел бы использовать разные пути для каждого контроллера без перезагрузки Item.html.
1) это возможно?
2) Если это невозможно, есть ли лучший подход к созданию пути на контроллер по сравнению с тем, что я здесь придумал?
app.js
var app = angular.module('myModule', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/items', {templateUrl: 'partials/items.html', controller: ItemsCtrl}).
when('/items/:itemId/foo', {templateUrl: 'partials/item.html', controller: ItemFooCtrl}).
when('/items/:itemId/bar', {templateUrl: 'partials/item.html', controller: ItemBarCtrl}).
otherwise({redirectTo: '/items'});
}]);
Item.html
<!-- Menu -->
<a id="fooTab" my-active-directive="view.name" href="#/item/{{item.id}}/foo">Foo</a>
<a id="barTab" my-active-directive="view.name" href="#/item/{{item.id}}/bar">Bar</a>
<!-- Content -->
<div class="content" ng-include="" src="view.template"></div>
controller.js
// Helper function to load $scope.item if refresh or directly linked
function itemCtrlInit($scope, $routeParams, MyService) {
$scope.item = MyService.currentItem;
if (!$scope.item) {
MyService.currentItem = MyService.get({itemId: $routeParams.itemId});
$scope.item = MyService.currentItem;
}
}
function itemFooCtrl($scope, $routeParams, MyService) {
$scope.view = {name: 'foo', template: 'partials/itemFoo.html'};
itemCtrlInit($scope, $routeParams, MyService);
}
function itemBarCtrl($scope, $routeParams, MyService) {
$scope.view = {name: 'bar', template: 'partials/itemBar.html'};
itemCtrlInit($scope, $routeParams, MyService);
}
Разрешение.
Положение дел : использование поискового запроса, как рекомендовано в принятом ответе, позволило мне предоставить разные URL-адреса без перезагрузки основного контроллера.
app.js
var app = angular.module('myModule', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/items', {templateUrl: 'partials/items.html', controller: ItemsCtrl}).
when('/item/:itemId/', {templateUrl: 'partials/item.html', controller: ItemCtrl, reloadOnSearch: false}).
otherwise({redirectTo: '/items'});
}]);
Item.html
<!-- Menu -->
<dd id="fooTab" item-tab="view.name" ng-click="view = views.foo;"><a href="#/item/{{item.id}}/?view=foo">Foo</a></dd>
<dd id="barTab" item-tab="view.name" ng-click="view = views.bar;"><a href="#/item/{{item.id}}/?view=foo">Bar</a></dd>
<!-- Content -->
<div class="content" ng-include="" src="view.template"></div>
controller.js
function ItemCtrl($scope, $routeParams, Appts) {
$scope.views = {
foo: {name: 'foo', template: 'partials/itemFoo.html'},
bar: {name: 'bar', template: 'partials/itemBar.html'},
}
$scope.view = $scope.views[$routeParams.view];
}
directives.js
app.directive('itemTab', function(){
return function(scope, elem, attrs) {
scope.$watch(attrs.itemTab, function(val) {
if (val+'Tab' == attrs.id) {
elem.addClass('active');
} else {
elem.removeClass('active');
}
});
}
});
Содержимое внутри моих частей обернуто ng-controller=...
Ответы:
Если вам не нужно использовать URL-адреса, такие как
#/item/{{item.id}}/foo
и,#/item/{{item.id}}/bar
но#/item/{{item.id}}/?foo
и#/item/{{item.id}}/?bar
вместо этого, вы можете настроить свой маршрут,/item/{{item.id}}/
чтобы он былreloadOnSearch
установлен наfalse
( https://docs.angularjs.org/api/ngRoute/provider/$routeProvider ). Это говорит AngularJS не перезагружать представление, если поисковая часть URL изменяется.источник
ng-controller="view.controller"
вng-include
директиву.<div ng-controller="itemFooCtrl">... your template content...</div>
. РЕДАКТИРОВАТЬ: Рад видеть, что вы решили, было бы здорово, если бы вы обновили свой вопрос, как вы решили, возможно, с помощью jsFiddle.Если вам нужно изменить путь, добавьте его после .config в файле приложения. Тогда вы можете сделать,
$location.path('/sampleurl', false);
чтобы предотвратить перезагрузкуБлагодарим за https://www.consolelog.io/angularjs-change-path-without-reloading за самое элегантное решение, которое я нашел.
источник
$timeout(un, 200);
до оператора return, так как иногда$locationChangeSuccess
вообще не срабатывал послеapply
(и маршрут не менялся, когда это действительно необходимо). Мое решение проясняет ситуацию после вызова пути (..., false)почему бы просто не поставить ng-контроллер на один уровень выше,
И не устанавливайте контроллер на маршруте,
меня устраивает.
источник
Для тех, кому нужно изменить path () без перезагрузки контроллеров - вот плагин: https://github.com/anglibs/angular-location-update
Использование:
Основано на https://stackoverflow.com/a/24102139/1751321
PS Это решение https://stackoverflow.com/a/24102139/1751321 содержит ошибку после вызова пути (, false) - оно будет нарушать навигацию браузера вперед / назад до вызова пути (, true)
источник
Хотя этот пост старый и получил ответ, использование reloadOnSeach = false не решает проблему для тех из нас, кому необходимо изменить фактический путь, а не только параметры. Вот простое решение для рассмотрения:
Используйте ng-include вместо ng-view и назначьте свой контроллер в шаблоне.
Единственным недостатком является то, что вы не можете использовать атрибут разрешения, но это довольно легко обойти. Также вы должны управлять состоянием контроллера, например, логикой, основанной на $ routeParams, когда маршрут изменяется в контроллере при изменении соответствующего URL.
Вот пример: http://plnkr.co/edit/WtAOm59CFcjafMmxBVOP?p=preview
источник
Я использую это решение
Этот подход сохраняет функциональность кнопки возврата, и у вас всегда есть текущий routeParams в шаблоне, в отличие от некоторых других подходов, которые я видел.
источник
Ответы выше, включая GitHub, имели некоторые проблемы для моего сценария, а также кнопка «Назад» или прямое изменение URL из браузера перезагружало контроллер, что мне не нравилось. Я наконец пошел со следующим подходом:
1. Определите свойство в определениях маршрутов, которое называется noReload для тех маршрутов, где вы не хотите, чтобы контроллер перезагружался при изменении маршрута.
2. В функции запуска вашего модуля поместите логику, которая проверяет эти маршруты. Это предотвратит перезагрузку , только если
noReload
этоtrue
и предыдущий контроллер маршрут тот же.3. Наконец, в контроллере прослушайте событие $ routeUpdate, чтобы вы могли делать все, что вам нужно, когда изменяются параметры маршрута.
Имейте в виду, что при таком подходе вы ничего не меняете в контроллере, а затем соответственно обновляете путь. Это наоборот. Сначала вы изменяете путь, а затем слушаете событие $ routeUpdate, чтобы изменить вещи в контроллере при изменении параметров маршрута.
Это делает вещи простыми и последовательными, поскольку вы можете использовать одну и ту же логику как при простом изменении пути (но без дорогостоящих запросов $ http, если хотите), так и при полной перезагрузке браузера.
источник
Существует простой способ изменить путь без перезагрузки
Используйте этот код для изменения URL, страница не будет перенаправлена
Второй параметр «ложь» очень важен.
источник
Вот мое более полное решение, которое решает несколько проблем, которые пропустили @Vigrond и @rahilwazir:
$routeUpdate
.$locationChangeSuccess
он никогда не запускается, что приводит к предотвращению следующего обновления маршрута.Если в том же цикле дайджеста был другой запрос на обновление, на этот раз желающий перезагрузить, обработчик события отменил бы эту перезагрузку.
источник
path
в конце должна бытьparam
, также это не работает с хешами, и URL в моей адресной строке не обновляетсяДобавить следующий внутренний тег
Это предотвратит перезагрузку.
источник
Начиная с версии 1.2, вы можете использовать $ location.replace () :
источник