Es wurde schon einmal gefragt und nach den Antworten sieht es nicht gut aus. Ich möchte mit diesem Beispielcode in Betracht ziehen ...
Meine App lädt das aktuelle Element in den Dienst, der es bereitstellt. Es gibt mehrere Controller, die die Artikeldaten bearbeiten, ohne dass der Artikel neu geladen wird.
Meine Controller laden das Element neu, wenn es noch nicht festgelegt ist. Andernfalls wird das aktuell geladene Element aus dem Dienst zwischen den Controllern verwendet.
Problem : Ich möchte für jeden Controller unterschiedliche Pfade verwenden, ohne Item.html neu zu laden.
1) Ist das möglich?
2) Wenn dies nicht möglich ist, gibt es einen besseren Ansatz für einen Pfad pro Controller als den, den ich hier gefunden habe?
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);
}
Auflösung.
Status : Durch die Verwendung der Suchabfrage, wie in der akzeptierten Antwort empfohlen, konnte ich verschiedene URLs angeben, ohne den Hauptcontroller neu laden zu müssen.
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');
}
});
}
});
Der Inhalt in meinen Teilbereichen ist mit verpackt ng-controller=...
Antworten:
Wenn Sie auf URLs nicht verwenden wie
#/item/{{item.id}}/foo
und#/item/{{item.id}}/bar
aber#/item/{{item.id}}/?foo
und#/item/{{item.id}}/?bar
stattdessen können Sie Ihre Route einrichten für/item/{{item.id}}/
habenreloadOnSearch
Satzfalse
( https://docs.angularjs.org/api/ngRoute/provider/$routeProvider ). Dadurch wird AngularJS angewiesen, die Ansicht nicht neu zu laden, wenn sich der Suchteil der URL ändert.quelle
ng-controller="view.controller"
zurng-include
Direktive hinzugefügt .<div ng-controller="itemFooCtrl">... your template content...</div>
. EDIT: Schön zu sehen, dass Sie gelöst wurden. Es wäre großartig, wenn Sie Ihre Frage mit der Art und Weise, wie Sie sie gelöst haben, aktualisieren würden, vielleicht mit einer jsFiddle.Wenn Sie den Pfad ändern müssen, fügen Sie diesen nach Ihrer .config in Ihre App-Datei ein. Dann können Sie
$location.path('/sampleurl', false);
das Nachladen verhindernDie eleganteste Lösung, die ich gefunden habe, finden Sie unter https://www.consolelog.io/angularjs-change-path-without-reloading .
quelle
$timeout(un, 200);
vor der Rückgabe eine Anweisung hinzufügen , da diese manchmal$locationChangeSuccess
überhaupt nicht ausgelöst wurdeapply
(und die Route nicht geändert wurde, wenn sie wirklich benötigt wurde). Meine Lösung klärt die Dinge nach dem Aufrufen des Pfades (..., false)warum nicht einfach den ng-controller eine ebene höher stellen,
Und stellen Sie den Controller nicht in die Route ein,
Für mich geht das.
quelle
Für diejenigen, die eine Änderung von path () ohne erneutes Laden der Controller benötigen - Hier ist das Plugin: https://github.com/anglibs/angular-location-update
Verwendung:
Basierend auf https://stackoverflow.com/a/24102139/1751321
PS Diese Lösung https://stackoverflow.com/a/24102139/1751321 enthält einen Fehler nach dem Aufruf von path (, false) - sie unterbricht die Browsernavigation vorwärts / rückwärts, bis path (, true) aufgerufen wird
quelle
Obwohl dieser Beitrag alt ist und eine Antwort akzeptiert wurde, löst die Verwendung von reloadOnSeach = false das Problem nicht für diejenigen von uns, die den tatsächlichen Pfad und nicht nur die Parameter ändern müssen. Hier ist eine einfache Lösung:
Verwenden Sie ng-include anstelle von ng-view und weisen Sie Ihren Controller in der Vorlage zu.
Der einzige Nachteil ist, dass Sie das Auflösungsattribut nicht verwenden können, aber das ist ziemlich einfach zu umgehen. Außerdem müssen Sie den Status des Controllers verwalten, z. B. eine Logik, die auf $ routeParams basiert, wenn sich die Route innerhalb des Controllers ändert, wenn sich die entsprechende URL ändert.
Hier ist ein Beispiel: http://plnkr.co/edit/WtAOm59CFcjafMmxBVOP?p=preview
quelle
Ich benutze diese Lösung
Bei diesem Ansatz bleibt die Funktionalität der Zurück-Schaltfläche erhalten, und Sie haben im Gegensatz zu einigen anderen Ansätzen, die ich gesehen habe, immer die aktuellen routeParams in der Vorlage.
quelle
Die obigen Antworten, einschließlich des GitHub, hatten einige Probleme für mein Szenario und auch das Zurück-Button oder die direkte URL-Änderung vom Browser luden den Controller neu, was mir nicht gefiel. Ich habe mich schließlich für folgenden Ansatz entschieden:
1. Definieren Sie eine Eigenschaft in Routendefinitionen mit dem Namen 'noReload' für Routen, bei denen der Controller bei Routenänderungen nicht neu geladen werden soll.
2. Fügen Sie in die Ausführungsfunktion Ihres Moduls die Logik ein, die nach diesen Routen sucht. Das Neuladen wird nur dann verhindert, wenn dies der Fall
noReload
isttrue
und der vorherige Routencontroller identisch ist.3. Hören Sie abschließend im Controller das Ereignis $ routeUpdate ab, damit Sie alles tun können, was Sie tun müssen, wenn sich die Routenparameter ändern.
Beachten Sie, dass Sie mit diesem Ansatz keine Änderungen am Controller vornehmen und den Pfad dann entsprechend aktualisieren. Es ist anders herum. Sie ändern zuerst den Pfad und hören dann das Ereignis $ routeUpdate ab, um Änderungen im Controller vorzunehmen, wenn sich die Routenparameter ändern.
Dies hält die Dinge einfach und konsistent, da Sie dieselbe Logik verwenden können, sowohl wenn Sie einfach den Pfad ändern (aber ohne teure $ http-Anforderungen, wenn Sie möchten) als auch wenn Sie den Browser vollständig neu laden.
quelle
Es gibt eine einfache Möglichkeit, den Pfad zu ändern, ohne ihn neu zu laden
Verwenden Sie diesen Code, um die URL zu ändern. Die Seite wird nicht umgeleitet
Der zweite Parameter "false" ist sehr wichtig.
quelle
Hier ist meine umfassendere Lösung, die einige Probleme löst, die @Vigrond und @rahilwazir übersehen haben:
$routeUpdate
.$locationChangeSuccess
wird sie nie ausgelöst, wodurch die nächste Routenaktualisierung verhindert wird.Wenn im selben Digest-Zyklus eine weitere Aktualisierungsanforderung vorhanden war, die dieses Mal neu geladen werden soll, bricht der Ereignishandler dieses Neuladen ab.
quelle
path
am Ende sollte seinparam
, auch dies funktioniert nicht mit Hashes, und die URL in meiner Adressleiste wird nicht aktualisiertFügen Sie das folgende innere Kopf-Tag hinzu
Dies verhindert das Nachladen.
quelle
Seit ungefähr Version 1.2 können Sie $ location.replace () verwenden :
quelle