Angular.js: Option auf $location, um Hash-/Pfadänderungen zuzulassen, ohne die Route neu zu laden

Erstellt am 12. Dez. 2012  ·  194Kommentare  ·  Quelle: angular/angular.js

Wir haben ein Paradigma in unserer App, dass Benutzer neue Dinge auf derselben Seite erstellen, auf der sie Dinge anzeigen. Unsere Route ist also /thing/:id. Wenn sie ein neues Ding erstellen, gehen sie zu /thing/new. Sobald das Ding erfolgreich gespeichert wurde, möchten wir die Route auf /thing/1234 (oder wie auch immer seine neue ID lautet) ändern. Jetzt muss der Teil nicht neu geladen werden, da die Daten alle gleich sind. Wir möchten nur, dass der Pfad aktualisiert wird, damit ein Benutzer jetzt den richtigen Link usw. mit einem Lesezeichen versehen kann.

Eine Option für $location (nicht in der Routendefinition) zum Aktivieren/Deaktivieren des Routenladens zu haben, würde funktionieren, aber ich bin mir sicher, dass es andere Möglichkeiten gibt, die Funktion zu implementieren.

Lots of comments $location ngRoute high confusing feature

Hilfreichster Kommentar

Die Lösung besteht im Wesentlichen darin, $location.path() einen zusätzlichen Parameter hinzuzufügen.

app.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
    var original = $location.path;
    $location.path = function (path, reload) {
        if (reload === false) {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        }
        return original.apply($location, [path]);
    };
}]);

Und dann einfach so verwenden

$location.path('/path/that/you/need', false);

Alle 194 Kommentare

+1, habe das gleiche Problem.

@cgross Da der $location-Dienst eine Methodenverkettung im JQuery-Stil verwendet und alle Befehle sowieso bis $digest zurückgestellt werden, schlage ich vor, eine neue Verkettungsmethode hinzuzufügen, z. B. reload(boolean):

$location.path("/thing/"+thing.id).replace().reload(false)

PS Ist das der Chris Gross, der das Eclipse-Nebel-Projekt gestartet hat?

Jep :)

+1 :+1:

+1

Im Moment verwenden wir einen schmutzigen Hack, um dieses Problem zu umgehen.

    $scope.$on('$locationChangeSuccess', function(event) {

        // Want to prevent re-loading when going from /dataEntry/1 to some other dataEntry path
        if ($route && $route.current && $route.current.$route.templateUrl.indexOf('dataEntry') > 0) {
            $route.current = lastRoute; //Does the actual prevention of routing
        }
});

+1

+1

+1

+1

+1

Hier ist mein Versuch, dies zu beheben, indem ich preventDefault() für $routeChangeStart . Was denkst du darüber?
Commit: https://github.com/redhotsly/angular.js/commit/f8ac46e6ac9d76cf855077d21b68b4c2c8043db1

Ich habe mich ein paar Tage mit dem notify Methode erstellt, mit der Sie die Benachrichtigung zum Standortwechsel einmal überspringen können. Dadurch sollte vermieden werden, dass eine Routenänderung oder ein Neuladen ausgelöst wird.

Dies berührt nicht das Routing-System, sodass Sie Ihre Routendefinitionen nicht ändern müssen. Es funktioniert auch dann noch, wenn Sie ui-router anstelle des standardmäßigen AngularJS-Routingsystems verwenden.

Beispiel: $location.path('/client/2').replace().notify(false);

Ich habe auch einige Tests und Dokumentationsbits bearbeitet.

+1

noch +1
Verwenden Sie bereits die Pull-Anfrage von

+1

+1

Leider wurde die PR https://github.com/angular/angular.js/pull/2398 vom Angular-Team abgelehnt, da das Überspringen von Benachrichtigungen zu Inkonsistenzen zwischen der tatsächlichen URL und der aktuellen Route führen könnte. Am Ende der Diskussion gibt es eine lange Erklärung.

Ich benötige dieses Feature in keinem meiner Projekte, aber ich behalte es in meinem Repository, damit es auf Wunsch zusammengeführt werden kann. Lassen Sie es mich einfach wissen, wenn es nicht mehr mit dem Master-Zweig synchron ist, damit ich die Änderungen neu aufbauen kann. Danke!

+1

+1, brauche das :(

+1

Edit: besserer Ansatz hier: https://github.com/angular/angular.js/issues/1699#issuecomment -22511464

Ich habe eine wiederverwendbare Fabrik erstellt, um dies zu umgehen (basierend auf der Idee von @shahmirn):

/**
 * HACK Do not reload the current template if it is not needed.
 *
 * See AngularJS: Change hash and route without completely reloading controller http://stackoverflow.com/questions/12115259/angularjs-change-hash-and-route-without-completely-reloading-controller
 */
app.factory('DoNotReloadCurrentTemplate', ['$route', function($route) {
  return function(scope) {
    var lastRoute = $route.current;
    scope.$on('$locationChangeSuccess', function() {
      if (lastRoute.$$route.templateUrl === $route.current.$$route.templateUrl) {
        console.log('DoNotReloadCurrentTemplate not reloading template: ' + $route.current.$$route.templateUrl);
        $route.current = lastRoute;
      }
    });
  };
}]);

Wie benutzt man:

app.controller('MyCtrl',
  ['$scope', 'DoNotReloadCurrentTemplate',
  function($scope, DoNotReloadCurrentTemplate) {

  DoNotReloadCurrentTemplate($scope);
}]);

Quelle: http://stackoverflow.com/a/16496112/990356

Wenn Sie "reloadOnSearch" auf der Route auf false setzen, scheinen die Hash-Änderungen durch das Neuladen der gesamten Seite zu beheben.

+1

Dies wäre großartig für mobile Apps, bei denen der Lebenszyklus zum Erstellen/Zerstören von ng-View nicht angemessen ist (Leistung und Benutzerfreundlichkeit beeinträchtigen).

@tkrotoff Danke für das Beispiel. Da Ihre Problemumgehung Ereignisbenachrichtigungen abbricht, habe ich eine Übertragung im Rootscope hinzugefügt, damit andere Controller weiterhin über die Routenänderung benachrichtigt werden können:

/**
 * HACK Do not reload the current template if it is not needed.
 *
 * See AngularJS: Change hash and route without completely reloading controller http://stackoverflow.com/questions/12115259/angularjs-change-hash-and-route-without-completely-reloading-controller
 */
app.factory('DoNotReloadCurrentTemplate', ['$route', '$rootScope', function($route, $rootScope) {
  return function(scope) {
    var lastRoute = $route.current;
    scope.$on('$locationChangeSuccess', function() {
      if (lastRoute.$$route.templateUrl === $route.current.$$route.templateUrl) {
        console.log('DoNotReloadCurrentTemplate not reloading template: ' + $route.current.$$route.templateUrl);
        $rootScope.$broadcast('locationChangedWithoutReload', $route.current);
        $route.current = lastRoute;        
      }
    });
  };
}]);

Dann:

app.controller('MyCtrl',
  ['$scope', 'DoNotReloadCurrentTemplate',
  function($scope, DoNotReloadCurrentTemplate) {

  DoNotReloadCurrentTemplate($scope);

  $rootScope.$on('locationChangedWithoutReload', function(event, route) {
    // set location specific breadcrumbs
    $scope.breadcrumbs = assembleBreadCrumbs();

    // do something for specific route
    if (route.$$route.action == 'item') {
      $scope.item = $scope.items[params.itemId];
      $rootScope.title = $scope.item.name;
    }
  });
}]);

Ich habe das gleiche Problem wie der Autor des Themas und habe eine modifizierte Version der oben beschriebenen Lösung erstellt.

app.factory('skipReload', [
    '$route',
    '$rootScope',
    function ($route, $rootScope) {
        return function () {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        };
    }
]);

Verwendung:

app.controller('ThingCtrl', ['$scope', '$http', '$location', 'skipReload', function ($scope, $http, $location, skipReload) {
    ...
    $scope.submit = function () {
        ...
        $http.post('thing', thing).success(function (id) {
            skipReload();
            $location.path('/thing/' + id).replace();
        });
    };
}]);

Die Verwendung eines permanenten Ereignis-Listeners, der templateUrl testet, um zu entscheiden, ob das erneute Laden der Route zugelassen wird, könnte das Routing zu anderen Ansichten unterbrechen, die dieselbe templateUrl verwenden. Zum Beispiel bin ich zu /thing/new geroutet und die Ansicht zeigt den Link zum zuletzt hinzugefügten Ding /thing/5 an. Ein weiteres Problem beim Testen von templateUrl besteht darin, dass Vorlagen mithilfe der Vorlageneigenschaft (als Zeichenfolge oder Funktion) angegeben werden können.

Dieser Hack ermöglicht es, genau ein Neuladen der Route zu überspringen und unterbricht das Routing nicht.

Ich habe auch eine weniger ausführliche Lösung (für die Verwendung im Controller) ausprobiert:

app.factory('location', [
    '$location',
    '$route',
    '$rootScope',
    function ($location, $route, $rootScope) {
        $location.skipReload = function () {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
            return $location;
        };
        return $location;
    }
]);
app.controller('ThingCtrl', ['$scope', '$http', 'location', function ($scope, $http, location) {
    ...
    $scope.submit = function () {
        ...
        $http.post('thing', thing).success(function (id) {
            location.skipReload().path('/thing/' + id).replace();
        });
    };
}]);

Scheint gut zu funktionieren.

+1

@sergey-buturlakin dein $location.skipReload ist einfach wunderbar! Ich verwende es anstelle von DoNotReloadCurrentTemplate

@sergey-buturlakin Ihre Lösung scheint für mich zu funktionieren. Danke!

Nachdem skipReload() von https://github.com/angular/angular.js/issues/1699#issuecomment -22511464 ausgeführt wurde, wird das Nachladen weiterhin deaktiviert
es sieht so aus, als ob un() später aufgerufen werden sollte

Es verhindert jedes erneute Laden und sollte direkt vor der Pfadänderung aufgerufen werden.
Wenn die Pfadänderung abgeschlossen ist, wird "un" aufgerufen.

ja, aber ich wollte das Nachladen nur einmal überspringen, aber der vorgeschlagene Ansatz verhindert jedes weitere Nachladen

+1

+1

+1

PR https://github.com/angular/angular.js/pull/2398 überspringt das Neuladen nur einmal. Ich weiß nicht, ob es Zusammenführungskonflikte mit dem aktuellen Master gibt. Wenn das der Fall ist, schreiben Sie mir einfach eine Nachricht und ich werde es reparieren.

Ich benutze die Lösung von Sergey, während ich die (meiner Meinung nach) nutzlose Variable "un" lösche und rufe.

Dies führt zu:

  angular.module('services.locationChanger', [])
    .service('locationChanger', ['$location', '$route', '$rootScope', function ($location, $route, $rootScope) {

        this.skipReload = function () {
            var lastRoute = $route.current;
            $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
            });
            return this;
        };

        this.withoutRefresh = function (url, doesReplace) {
            if(doesReplace){
                $location.path(url).replace();
            }
            else {
                $location.path(url || '/');
            }
        };
    }]);

und jeder Anrufer:

 locationChanger.skipReload().withoutRefresh("/", true);

+1

+1

+1

+1

@mica16 Wird nicht die Variable un verwendet, um die Bindung des Ereignisses aufzuheben?

Ich habe zwei Plunkr zum Testen erstellt, mit und ohne die Variable un , um die Ereignisse zu lösen, und es scheint, dass das Ereignis ohne sie immer wieder ausgelöst wird

Ja, die Variable un hört sich seltsam an.
Laut dem ursprünglichen Autor würde es als nützlich angesehen..aber ich bin nicht davon überzeugt, dass dies die perfekte Lösung ist.

Ich habe es vorgezogen, es neu zu schreiben, aber ich habe das Feature verworfen, da ich es nicht mehr erwarte.

Machen Sie also mit, wenn Ihr Komponententest sicherstellen kann, dass er so funktioniert, wie Sie es erwarten :)

Ihr habt Recht Jungs
Meine Lösung war

app.factory 'location', ['$location', '$route', '$rootScope', '$timeout', ($location, $route, $rootScope, $timeout) ->
  $location.skipReload = ->
    lastRoute = $route.current
    un = $rootScope.$on('$locationChangeSuccess', ->
      $route.current = lastRoute
    )
    $timeout((->
      un()
    ), 1000)
    $location

  $location
]

dann im Controller

location.skipReload().path('/new/path').replace()

+1

+1

+1

+1

Eine andere Möglichkeit besteht darin, es aus dem aktuellen Javascript-"Schritt" zu entfernen, damit Route die an der window.location vorgenommene Änderung nicht erkennt:

setTimeout(function() {
    window.location.hash = "";
    if (typeof (history.pushState) !== "undefined") {
        history.pushState("", document.title, location.pathname);
    }
}, 0);

+1

+1

+1

+1

Wie wäre es mit $anchorScroll? Ich habe im Netz herumgestöbert und herausgefunden, dass es dafür einige Tools gibt. Bei mir funktioniert es zumindest.

Sie sollten es sich ansehen :

+1

Ist das eine schlechte Idee? Ich gebe zu, dass ich es nicht ausgiebig getestet habe. Ich mochte die Idee nicht, vor dem Festlegen des Pfads eine separate Methode aufzurufen. Zumindest aus Sicht der Nutzung scheint dies sauberer zu sein.

Ich habe die eingebaute Funktion $location.path mit der Technik von Sergey erweitert.

App.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
        var original = $location.path;
        $location.path = function (path, reload) {
            if (reload === false) {
                var lastRoute = $route.current;
                var un = $rootScope.$on('$locationChangeSuccess', function () {
                    $route.current = lastRoute;
                    un();
                });
            }

            return original.apply($location, [path]);
        };
    }])

Verwendung:

$location.path('/my/path', false);

+1

@EvanWinstanley- Lösungen funktionieren für mich, danke!

+1

Der Fix von @EvanWinstanley/sergey sieht gut aus und lädt den Controller nicht neu, aber beim Ändern der Route werden erneut Auflösungen angefordert.

Mein Hauptanwendungsfall dafür wäre, $location.path manuell zu ändern, ohne die Auflösungen/Controller neu zu laden, damit ich Caching durchführen kann.

Zum Beispiel: Ich habe eine Auswahl, die es einem Benutzer ermöglicht, zwischen mehreren Anwendungen zu wählen, was auch den $location.path für schönere URLs ändert. Wenn ein Benutzer eine Anwendung auswählt, werden die Ergebnisse des API-Aufrufs zwischengespeichert. Selbst mit dem Fix wird die Auflösung immer erneut durchgeführt, was unnötig ist, da die Ergebnisse bereits zwischengespeichert sind.

+1

@sergey-buturlakin-Lösung funktioniert für mich gut, sie lädt den Controller nicht neu, lädt aber immer noch die Reslove-Funktion neu und sendet eine Anfrage an den Server.

+1

Die Lösung von @EvanWinstanley funktioniert bei mir nicht. Auf der anderen Seite funktionierte die Lösung von

+1

+1

+1

+1
Bitte unterstützen Sie: $location.reload();

@jvmvik hast du es mit $route.current.reload() versucht?

7.1.1

nach über einem jahr keine neuigkeit dazu?

+1

+1

Ich habe Sergeys Lösung ein wenig verbessert.
Jetzt unterstützt es zB benutzerdefinierte URLs für Tabs (Navigations-Tabs), ohne die ganze Seite neu zu laden.

// Original: https://github.com/angular/angular.js/issues/1699#issuecomment-22511464
//
// Usage:
//
// (interception is needed for Back/Forward buttons to work)
//
// location.intercept($scope._url_pattern, function(matched) {
//   // can return false to abort interception
//   var type = matched[1]
//   if (!type) {
//     return;
//   }
//   $scope.safeApply(function() {
//     $scope.data_type = type; 
//     $scope.params.page = 1; 
//     $scope.get_data(); 
//   });
// });
// 
// anywhere in your controller: 
// location.skipReload().path(url);
//
// to replace in history stack:
// location.skipReload().path(url).replace();

app.factory('location', [
    '$location',
    '$route',
    '$rootScope',
    function ($location, $route, $rootScope) {
        var page_route = $route.current;

        $location.skipReload = function () {
            //var lastRoute = $route.current;
            var unbind = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = page_route;
                unbind();
            });
            return $location;
        };

        if ($location.intercept) {
            throw '$location.intercept is already defined';
        }

        $location.intercept = function(url_pattern, load_url) {

            function parse_path() {
                var match = $location.path().match(url_pattern)
                if (match) {
                    match.shift();
                    return match;
                }
            }

            var unbind = $rootScope.$on("$locationChangeSuccess", function() {
                var matched = parse_path();
                if (!matched || load_url(matched) === false) {
                  return unbind();
                }
                $route.current = page_route;
            });
        };

        return $location;
    }
]);

+1

+1

Eine andere Problemumgehung, um das Neuladen der Route beim Ändern des $location-Pfads zu verhindern, besteht darin, die aktuellen Pfadparams so einzustellen, dass sie mit dem neuen Positionspfad übereinstimmen.

In meiner $routeProvider-Konfiguration habe ich eine Route zu /tasks wie folgt:

when('/tasks/:section/:taskId?', {
      templateUrl: 'partials/tasks.html',
      controller: 'TaskCtrl',
      reloadOnSearch: false
      })

Die obige Route hat zwei pathParams-Abschnitte und taskId (taskId ist optional) und reloadOnSearch ist auf false gesetzt.

Um beispielsweise von /tasks/inbox zu /tasks/inbox/122 zu navigieren, ohne die Route neu zu laden, setzen Sie die taskId pathParam, bevor Sie den $location-Pfad wie folgt ändern

$scope.showTask = function(task) {
    // set taskId to prevent route reloading
    $route.current.pathParams ['taskId'] = task.id;
    $location.path('/tasks/'+$route.current.pathParams ['section']+'/'+task.id);
};

Beachten Sie, dass der Abschnitt pathParam nicht gesetzt werden muss, da er bereits von der Route gesetzt wurde.

Wenn die Route feststellt, dass die aus dem neuen $location-Pfad extrahierten pathParams mit den aktuellen pathParams der Route übereinstimmen (und reloadOnSearch auf false gesetzt ist), wird sie die Route nicht neu laden, stattdessen wird ein $routeUpdate-Ereignis ausgelöst.

Um von /tasks/inbox/122 zu /tasks/inbox zurück zu navigieren, ohne die Route neu zu laden, löschen Sie die taskId pathParam, bevor Sie den $location-Pfad wie folgt ändern

$scope.back = function () {
    // delete taskId to prevent route reloading
    delete $route.current.pathParams ['taskId'];
    $location.path('/tasks/'+$route.current.pathParams ['section']);
};

+1

+:100:

Haben Sie den Artikel von Derick Bailey über den Backbone-Router http://lostechies.com/derickbailey/2011/08/28/dont-execute-a-backbone-js-route-handler-from-your-code/ gelesen? Backbone bietet diese Option und laut Derick sollten Sie immer vermeiden, ein Reload auszulösen (das scheint das Gegenteil von dem zu sein, was der Router von angle hier zu tun scheint).
Es gibt 48 "+1" in diesem Beitrag ... Ich glaube nicht, dass all diese Leute etwas falsch machen. var lastRoute = $route.current; speichern und später auf $locationChangeSuccess mit $route.current = lastRoute; wiederherstellen zu müssen, scheint ziemlich umständlich zu sein.
@IgorMinar hast du irgendwelche Gedanken?

OK, ich besitze dieses Thema für die nächste Woche, damit wir es endlich schließen können.

Das Wichtigste zuerst, ich denke nicht, dass die Route neu geladen werden sollte, wenn sich der #Hash-Wert ändert.

website.com/#/my-route#top

website.com/#/my-route#bottom

Wenn sich also von oben nach unten ändert, sollte es nicht neu geladen werden, aber wenn sich der Wert von my-route ändert, sollte dies der Fall sein. Da sind wir uns alle einig, oder?

Zweitens, was noch wichtiger ist, brauchen wir eine einfache Möglichkeit, darauf hinzuweisen, dass der Routenpfad bei einer Änderung nicht neu geladen wird. Dies wird jedoch problematisch, wenn sich ein früheres Fragment der Route ändert. Warum also nicht eine andere Notation für einen Routenparameter verwenden, indem wir zwei :: Doppelpunkte verwenden, um darauf hinzuweisen, dass er sich wie ein Platzhalterwert verhält.

// this will reload the page when the id changes like normal
$routeProvider.register('/users/:id')

// this will reload the page when the id changes, but not the section (since two colons are used)
$routeProvider.register('/users/:id/::section')

Was denkt ihr?

Dies hilft nicht wirklich in der Situation, in der Sie umziehen möchten:

/users/new

zu

/users/123

Sobald der neue Benutzer erstellt und ihm eine ID zugewiesen wurde, ohne den Benutzer neu zu laden, da er bereits vorhanden ist.

Denn irgendwie muss man das neue Benutzerobjekt dem aktuellen Benutzerobjekt mit der ID 123 zuordnen. Das ist eher anwendungsspezifisch, nein?

Für das, was es wert ist, unterstützt Ember Router auch keine Änderung der URL ohne Übergang:

http://stackoverflow.com/questions/19076834/change-url-ohne-übergang

@matsko Können wir den Ingenieur einfach ermächtigen und ihn oder sie entscheiden lassen, ob die Route eine Änderung auslösen soll oder nicht?
Ich bin mit guten Standardeinstellungen in Ordnung.
Erstellen Sie eine Möglichkeit, damit der Entwickler die URL ändern kann, ohne die gesamte Kette von Reload-Ereignissen auszuführen. Persönlich bin ich damit einverstanden, einen optionalen zusätzlichen Parameter mit Optionen (z. B.: {reload: false}) zu ".path()", ".search()" usw. hinzuzufügen.

@ChrisCinelli ja, aber was passiert, wenn eine Routendefinition zwei Parameter enthält? Wie können Sie verhindern, dass einer nachlädt, während Sie es dem anderen erlauben? Die Flagge wäre ein Alles-oder-Nichts-Feature.

@matsko Wird also auf der Implementierungsseite in Betracht gezogen, dass wir in der Lage sind, sich die

@cgross Cherry-Pick ja (mit dem Doppelpunkt). Dies ist erst einmal nur eine Idee, also nichts Konkretes. Wenn dies mit den Plänen für Angular 2.0 übereinstimmt, können wir es möglicherweise verwenden oder versuchen, etwas zu verwenden, das 2.0 geplant hat oder das Dart bereits hat (um die API konsistent zu halten).

Ich denke, das wäre perfekt und würde (zumindest IMO) als Teil der Route gut aussehen.

$routeProvider,when("/:categoryName/:id[reload=no]", { ... })

Und dann im Controller

$scope.$on("$routeChangeSuccess", function () {
  if ($routeParams.id !== $scope.activeId) {
    // React to ID update without reload
  }
});

Ja, so ähnlich, aber der Doppelpunkt '::id' würde anstelle von :id[reload=no] .

Denken Sie daran, dass dies nur eine Idee ist, aber viele Leute hier wollen diese Funktion.

Ich dachte daran, vielleicht irgendwann andere Optionen hinzuzufügen, aber ich denke, es gibt nicht wirklich andere Optionen, die es geben könnte. Es ist auch gut zu sehen, dass diese Bitte ernst genommen wird. Hübsche URLs sind für viele von uns eine große Sache.

Matsko +1 für doppelten Doppelpunkt, aber ich denke, es wäre auch nützlich, Optionen an path() auch für einige oben erwähnte Randfälle übergeben zu können

+1 für Doppelpunkt

@matsko hat mich gebeten, abzuwägen, wie wir dies im Router von Angular 2.0 handhaben. Ich weiß, dass es denjenigen von Ihnen, die dies für ng1.x brauchen, nicht hilft, aber ich dachte, es könnte für Sie interessant sein.

Der neue Router hat eine navigate Methode, an die Sie eine _url_ und ein optionales _options_ Objekt übergeben können. Dies basiert auf den Verlaufsfunktionen des Backbone-Routers und unterstützt daher zwei Optionen replace und trigger Wenn Sie ohne /users/new zu /users/123 wechseln möchten Um eine Bildschirmnavigation zu verursachen, geben Sie einfach trigger:false . Wenn Sie auch möchten, dass der Verlaufseintrag /users/new durch die neue id-basierte URL ersetzt wird, geben Sie auch replace:true .

Das Aktualisieren von Routen von einer _neuen_ Route zu einer _id-basierten_ Route ohne DOM-Transformationen usw. zu verursachen, ist ein wichtiger Anwendungsfall für diese API. Ein weiteres gängiges Beispiel ist die Paginierung. Wenn Sie beispielsweise ein Raster haben und möchten, dass der Benutzer durch die Daten blättert, können Sie dies verwenden, um das Fragment mit den aktuellen Seiteninformationen zu aktualisieren, ohne eine Navigation zu verursachen. Ich bin mir sicher, dass es noch andere Verwendungen gibt, aber diese sind die, die ich im Laufe der Jahre immer wieder in meiner Beratung gesehen habe.

Hoffe diese Info hilft. Vielleicht kann der 1.x-Router diese Technik übernehmen?

@EisenbergEffect also zur Bestätigung. Für 1.x würde die Methode, um dies zu tun, ohne den Pfad zu ändern, so aussehen:

$location.path(value, { trigger : false })

Und dies würde den Pfad effektiv ersetzen, ohne dass die neue Route + Controller darauf aufmerksam wird. Das könnte im Moment funktionieren, aber was halten Sie von der Idee mit dem doppelten :: Doppelpunkt?

Für alle anderen hier, möchten Sie lieber, dass die URL-Änderung (ohne die Route neu zu laden) durch die Route oder durch den Entwickler erleichtert wird, wenn die URL geändert wird?

Es sollte eine zentrale Quelle der Wahrheit für den Standort geben, wie einen Dienst, der
Routen und Browser können sowohl verweisen als auch beeinflussen, bleiben aber das Einzige
Wahrheit
Am 1. Juli 2014, 23:28 Uhr, schrieb "Matias Niemelä" [email protected] :

@EisenbergEffect https://github.com/EisenbergEffect also zur Bestätigung. Für
1.x, die Methode, um dies zu tun, ohne den Pfad zu ändern, würde so aussehen:

$location.path(value, { trigger : false })

Und dies würde den Pfad effektiv ersetzen, ohne die neue Route zu verursachen

  • Controller bewusst werden. Das könnte vorerst funktionieren, aber wie fühlst du dich?
    über die doppelte :: Doppelpunkt-Idee?

Für alle anderen hier, möchten Sie lieber die URL ändern (ohne
Umladen der Route) durch die Route oder durch den Entwickler erleichtert werden
wenn die URL geändert wird?


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/angular/angular.js/issues/1699#issuecomment -47741350.

Hier ist eine andere Idee... Erlauben Sie zwei neue Methoden für jede Routendefinition, sagen wir entering(transitionInfo) und leaving(transitionInfo) oder so. Wenn sie existieren, würde die Methode leaving auf der alten Route aufgerufen, bevor sie verlassen wird, und dann würde die Methode entering() auf der neuen Route aufgerufen. Das transitionInfo wäre ein Objekt, das wie folgt aussieht:

{
  newUrl: ...
  newRoute: ...
  oldUrl: ...
  oldRoute: ...
  cancelRouteChange: false,
  ignoreRouteChange: false
}

Bei dieser Methode können wir die alten und neuen Routen/URLs überprüfen und dann, wenn Sie möchten, dass sich die URL ändert, aber den Routenübergang nicht erneut ausführen, setzen Sie ignoreRouteChange auf true . Wenn Sie die Routenänderung abbrechen und zur vorherigen Route zurückkehren möchten, setzen Sie cancelRouteChange auf true.

Dies gibt dem Entwickler dann die vollständige Kontrolle darüber, wann Routenübergänge auftreten, funktioniert, wenn die URL direkt in der Adressleiste geändert wird, und lokalisiert auch die Funktionalität zur Entscheidung über eine bestimmte Routenänderung nahe der Definition der einzelnen Routen, die sich um die Änderung kümmern .

Ich glaube, es gibt etwas Ähnliches im AngularV2-Router namens activate() . @EisenbergEffect kannst du das bestätigen?

Was denkst du?

@matsko Ja, so könnte die API aussehen. Vielleicht möchten Sie auch die Option replace implementieren, da auch diese häufig benötigt wird. In diesem speziellen Fall von /users/new bis /users/123 würde ich denken, dass Sie beide Optionen nutzen würden, da Sie nicht wirklich möchten, dass /users/new im Backstack bleibt, nachdem der neue Benutzer ist erstellt.

Was das :: , bin ich mir nicht sicher, ob das ganz nützlich ist. Der Grund dafür ist, dass im obigen Benutzerbeispiel nicht das URL-Muster zählt, sondern der spezifische Anwendungskontext. Wenn Sie beispielsweise von customers zu users/123 wechseln, möchten Sie dies benachrichtigen. Wenn Sie users/new aufgeben und zu users/456 wechseln, möchten Sie auch benachrichtigen. Erst wenn Sie bei users/new und die Erstellung des neuen Benutzers abgeschlossen haben, möchten Sie einfach das Fragment aktualisieren, um die neu erstellte Benutzer-ID darzustellen, ohne dass ein Übergang verursacht wird. Dies hängt stark davon ab, was der Benutzer zu diesem Zeitpunkt im Kontext dieses Benutzerbildschirms tatsächlich tut.

@petebacondarwin Ein Problem bei dieser Idee ist, dass das Wissen über die Routendefinitionen global verfügbar ist. Vielmehr ist es in den jeweiligen Benutzercontroller eingebettet, da dieser Controller der Codeabschnitt ist, der weiß, ob ein neuer Benutzer in diesem Moment tatsächlich erstellt wird oder nicht, anstatt einfach vom neuen Benutzerbildschirm weg zu einem bereits existierenden Benutzer zu navigieren.

Für mich besteht der Weg darin, dem Anrufer, der eine Route ändern möchte, die Kontrolle zu geben. Ich bin also definitiv für zwei Optionen replace und trigger .

@EisenbergEffect - du hast recht. Im Allgemeinen sind diese Informationen nicht sofort verfügbar, obwohl ich mir vorstellen würde, dies wie folgt umzusetzen:

Haben Sie einen Dienst namens currentUser , der den Benutzer enthält, mit dem wir gerade arbeiten. Ich mache dies im Allgemeinen gerne, da ich meine Controller nicht mit Code überladen möchte. Wenn sich dies zu spezifisch anfühlt, könnten Sie currentEntity , was das aktuelle "Ding" ist, das Sie bearbeiten/ansehen.

Dann könnte die Methode route enter() dies einfügen und entscheiden, ob die Navigation zu dieser Route tatsächlich die aktuelle Entität ändern würde. Wenn nicht, machen wir uns nicht die Mühe, die Umstellung durchzuführen, sondern aktualisieren stattdessen einfach die URL.

Ich weiß es zu schätzen, dass dies in einer großen App etwas unhandlich werden könnte, aber ich dachte, ich würde es als Option wegwerfen.

Welche Argumente sprechen dagegen, dem Anrufer (dh dem, der die Route/URL-Änderung anfordert) die Kontrolle darüber zu geben, ob der Routenübergang tatsächlich stattfindet? Ich erinnere mich, dass @IgorMinar besorgt war, dass dies die Einschränkung

@petebacondarwin Das könnte für dieses spezielle Szenario funktionieren, aber es wird etwas schwieriger, das oben erwähnte Paginierungsbeispiel zu handhaben, das nicht auslösen und nicht ersetzen möchte, während das neue Benutzerszenario nicht auslösen, sondern ersetzen möchte.

Das Staatsproblem anzugehen ist etwas komplizierter. Der Grund dafür ist, dass wir zwei URLs haben, die den gleichen Controller-Zustand repräsentieren .... aber der Unterschied liegt im Modell. Wir haben also in Wirklichkeit zwei verschiedene Zustände....aber aus UX-Perspektive möchten wir den Benutzer nicht bei der Umstellung irritieren. Aus Perf-Perspektive möchten wir DOM nicht unnötig wegwerfen und alles neu erstellen. Im Fall des neuen Benutzers => gespeicherten Benutzerübergangs möchten wir also das Auslösen wirklich vermeiden und auch das Fragment ersetzen, damit der Zurück-Button Sie _nicht_ zurück zum Bildschirm des neuen Benutzers bringt. Intern müsste der Router oder Ortungsmechanismus nur verfolgen, was das aktuelle Fragment ist. (Ich gehe da ein wenig davon aus, da ich nicht weiß, wie ng1.x in dieser Hinsicht funktioniert. Bei 2.x achten wir darauf, das aktuelle/vorherige Fragment sorgfältig zu verfolgen, unabhängig davon, wie es geändert wurde.) das Paginierungsszenario möchten wir nicht auslösen, weil wir eine schöne UX zum Durchblättern der Daten wünschen und keine unnötige DOM-Beseitigung wünschen. Aber wir möchten, dass das vorherige Fragment beibehalten wird, damit der Benutzer die Zurück-Schaltfläche verwenden kann, um sich rückwärts durch die Datenseiten zu bewegen.

Beachten Sie, dass es in beiden Fällen nicht nur um die URL und den Zustand der App geht, sondern auch darum, wie wir vom aktuellen Zustand in diesen neuen Zustand übergehen. All dies spielt keine Rolle, wenn Sie einen Deep-Link direkt zur neuen Ansicht erstellen. Es spielt eine Rolle, wenn Sie im Kontext dieser sehr spezifischen Fälle von einem zum anderen wechseln.

+1

+1

+1

+1
Und auch eine Funktion zum Ändern der URL, ohne die Route zu ändern

+1 - schön zu sehen, dass ich das nicht allein will!

+1, noch nicht hinzugefügt(

+1

+1

+1

+1

+1

+1

+1

:+1:

Du auch @basarat? :Lächeln:

@johnnyreilly hat nur einen Dienst, bei dem Sie $route und $location injizieren und Sie können diese Funktion haben:

/** navigate */
    public navigate(url: string, reload = true) {
        this.$location.url(url);

        // Don't do a controller reload on this navigation. Note: *you* need to be careful not to actually *need* a controller reload
        if (!reload) {
            var lastRoute = this.$route.current;
            var unsub = this.$rootScope.$on('$locationChangeSuccess', () => {
                this.$route.current = lastRoute; // fake this to make the route logic think nothing changed
                unsub();
            });
        }
    }

Schön @basarat!

+1

+1

Eine Sache, die mir bei den aktuellen Lösungen auffällt, ist, dass mein Router-Resolve-Block immer noch ausgeführt wird. Ist das noch jemandem aufgefallen? Es war einfach, etwas im $route.current-Objekt zu übergeben, aber das scheint hackig zu sein. Außerdem scheint dieses Problem nie behoben zu werden? :schreien:

+1

+1

Für diejenigen unter euch, die nicht zurückscrollen wollen... soweit ich das beurteilen kann, ist dies das, was wir bisher haben (sorry Coffeescript). Leider funktioniert das bei mir nicht 100%. Ich bekomme immer noch meine resolve ausgeführt und die Zurück/Vorwärts-Tasten scheinen jetzt kaputt zu sein.

#
# Special $location.path function that allows you to change the url, but not
# send things through the router.
# <strong i="7">@see</strong> https://github.com/angular/angular.js/issues/1699
#
@app.run(['$rootScope', '$location', '$route', '$timeout', ($rootScope, $location, $route, $timeout) ->

    originalPath = $location.path

    $location.path = (url, reload=true) ->
        if ! reload
            lastRoute = $route.current
            if lastRoute
                unsub = $rootScope.$on('$locationChangeSuccess', ->
                    $route.current = lastRoute # fake this to make the route logic think nothing changed
                    $route.current.ignore = true
                    unsub()
                )
                # make sure to clean up and unregister the unsub function
                $timeout( ->
                    unsub()
                , 500)

        originalPath.apply($location, [url])

])

@lookfirst du unsub zweimal an. Bevorzugen: https://github.com/angular/angular.js/issues/1699#issuecomment -54931571

@basarat Achselzucken ... Ich habe das hinzugefügt, weil ich festgestellt habe, dass unsub() in Ihrem bevorzugten Beispiel nicht immer aufgerufen wird. Vielleicht wäre es am besten, einen Wächter in die unsub-Funktion einzufügen.

unsubbed = false
unsub = ... ->
    if ! unsubbed
        ...
        unsubbed = true
        unsub()

$timeout(unsub, 500)

Unabhängig davon ist diese Lösung ein totales Durcheinander. Es zerbricht alle möglichen Dinge. Wir brauchen wirklich einen eckigen, genehmigten Fix.

weil ich festgestellt habe, dass unsub() in Ihrem bevorzugten Beispiel nicht immer aufgerufen wurde

@lookfirst du verwendest location.path Ich verwende location.url . Das könnte sich darauf auswirken.

Nur pingelig (ich bin gerne hilfreich): statt originalPath.apply($location, [url]) kannst du originalPath.call($location, url) (du weißt das vielleicht schon)

Interessant... location.url funktioniert viel besser (der Zurück-Button funktioniert wieder!), scheint aber bei mir ein anderes Problem zu verursachen. Ich werde mich näher damit befassen müssen, wenn ich 10 Stunden lang nicht am Stück programmiert habe. Danke für die Hinweise und Diskussion, wirklich!

+1

+1

+1

@kuchumovn Deine Lösung ist großartig. Ein Problem, das ich habe, ist, dass sich $routeParams nicht ändert, nachdem sich der Pfad geändert hat. Ich habe es gelöst, indem ich den Wert von $routeParams in den Ereignislistenern ersetzt habe. Ich bin mir nicht sicher, ob das der richtige Weg ist, aber bei mir funktioniert es.

app.factory('Location', [
    '$location',
    '$route',
    '$rootScope',
    '$routeParams',
    function ($location, $route, $rootScope, $routeParams) {
        var page_route = $route.current;

        $location.skipReload = function () {
            //var lastRoute = $route.current;
            var unbind = $rootScope.$on('$locationChangeSuccess', function () {
                angular.copy($route.current.params, $routeParams);
                $route.current = page_route;
                unbind();
            });
            return $location;
        };

        if ($location.intercept) {
            throw '$location.intercept is already defined';
        }

        $location.intercept = function(url_pattern, load_url) {

            function parse_path() {
                var match = $location.path().match(url_pattern);
                if (match) {
                    match.shift();
                    return match;
                }
            }

            var unbind = $rootScope.$on("$locationChangeSuccess", function() {
                var matched = parse_path();
                if (!matched || load_url(matched) === false) {
                  return unbind();
                }
                angular.copy($route.current.params, $routeParams);
                $route.current = page_route;
            });
        };

        return $location;
    }
]);

+1

+1

Ich habe gestern persönlich mit @IgorMinar gesprochen... er sagt, dass die Zukunft der Router in Angular 2.0 ist, der bald wieder auf 1.3 portiert wird. Etwas zu bedenken...

warum willst du einfach ui-router in winklig zusammenführen?
Der uui-Router scheint ziemlich alles zu lösen, was benötigt werden kann.

stimme @elennaro zu. Obwohl ui-router etwas Kreativität und Studium erfordert, damit es funktioniert, tut es in jedem Szenario, das mir begegnet ist. Neugierig, was sind die Nachteile von ui-router und Google-Ressourcen darauf?

Es scheint, dass keine der Lösungen die Auflösung nicht ausführen wird, irgendwelche Ideen?

+1

+1

+1 für $location.path(value, { trigger : false })
Gibt es diesbezüglich Fortschritte?

+1

+1

+1 Was ist mit einer komplett separaten Methode? path() unverändert lassen und einfach eine $location.hash-Methode hinzufügen, die einfach die URL des Browsers ändert, ohne dass der Controller neu geladen wird. Dies ermöglicht es uns, die Rückwärtsnavigation des Browsers zu steuern und ist ein gültiges Anwendungsszenario in Rich-Anwendungen.

+1

Derzeit wird das Snippet hier auf dieser Seite verwendet: http://joelsaupe.com/programming/angularjs-change-path-without-reloading/

+1

+1

+1

Eine Problemumgehung, die ich gefunden habe, bestand darin, einen untergeordneten Zustand mit einer absoluten URL hinzuzufügen.

$stateProvider.state('state.child', {
    url: '^/some-other-url'
});

Dann machen Sie einfach $state.go('.child') und das sollte die URL in die gewünschte ändern, ohne neu zu laden und alle glücklich zu machen. Beachten Sie das Caret, das anzeigt, dass die URL nicht vom übergeordneten Element erbt. Ich habe eine Weile gebraucht, um dies herauszufinden.

+1

+1

+1

+1

+1

+1

+1

@btford wie wird damit (wenn überhaupt) im componentRouter umgegangen ?

Danke @balsarori für eine einfache, funktionierende Lösung .

Darüber hinaus ausgearbeitet, um die Aktualisierung der $route Pfadparameter zu ermöglichen, ohne den Controller neu zu laden.

Es verwendet console.log anstelle von $log da wir einfach alle Protokolle für Produktions-Builds mit uglifyjs entfernen können.

Bearbeiten: Fix bei Verwendung in einem Projekt:

/**
 * parameter handling
 */

'use strict';

angular.module('route-params', [
  'ng',
  'ngRoute',
])
.service('routeParams', function(
  $route,
  $location
) {
  var R = {};

  /**
   * <strong i="15">@ngdoc</strong> method
   * <strong i="16">@name</strong> routeParams#replace
   *
   * <strong i="17">@description</strong>
   * Replace route params, including path params, without reloading controller.
   *
   * Causes `$route` service to update the current URL, replacing
   * current route parameters with those specified in `params`.
   *
   * Provided property names that match the route's path segment
   * definitions will be interpolated into the location's path, while
   * remaining properties will be treated as query params.
   *
   * If `options.reload` is truthy, the current controller is reloaded.
   *
   * If `options.history` is truthy, the browser history is updated.
   * If `options.history` is undefined, the browser history is only updated
   * when changing value of any existing `$route` parameter,
   * ie. not when adding a previously undefined `$route` parameter.
   *
   * <strong i="18">@param</strong> {!Object<string, string>} params mapping of URL parameter names to values
   * <strong i="19">@param</strong> {!Object<string, boolean>} options `history` and `reload` options.
   *
   * <strong i="20">@returns</strong> {Object} self
   */
  R.replace = function(params, options) {
    var key, value, updateRequired;
    options = options || {};

    // Convert params to strings, and check if they differ from current route params.
    // If `options.history` is undefined, and passed params update any current route params, then set it to true.
    var currentParams = $route.current.params;

    console.log('route: params: replace', {last: angular.copy(currentParams), next: params,
      route: $route.current, options: options});

    if (!$route.current.$$route) {
      // Can't change location.
      return;
    }
    var currentPath = $route.current.$$route.originalPath;
    var history = options.history;

    for (key in params) {
      // jshint eqnull: true
      value = params[key] = (params[key] == null ? undefined : params[key] + '');

      if (value !== currentParams[key]) {
        updateRequired = true;

        console.log('route: params: replace: ' + (currentPath.search(':\\b' + key + '\\b') ? 'path.' : 'search.') +
          key + ' = ' + (key in $route.current.params ? $route.current.params[key] + ' -> ' : '') + params[key]);

        if (history === undefined && key in currentParams) {
          console.log('route: params: replace: update history: ' + key + ' = ' + currentParams[key] + ' -> ' + value);
          history = true;
        }
      }
    }

    if (updateRequired) {
      // If `options.reload` is falsey, then set current route `reloadOnSearch` to false,
      // and make passed path params equal with current route path params,
      // so that `$route` treats the change as update only, and does not broadcast `$routeChangeStart` event.
      //
      // See https://github.com/angular/angular.js/issues/1699#issuecomment-45048054
      // and https://github.com/angular/angular.js/tree/v1.3.x/src/ngRoute/route.js#L484
      // and https://github.com/angular/angular.js/tree/v1.3.x/src/ngRoute/route.js#L539
      if (!options.reload) {
        // Set current route `reloadOnSearch` to false.
        $route.current.$$route.reloadOnSearch = false;

        // Add any passed path params to current route path params, and convert them to strings.
        // Path params are detected by searching for respective name group `:key[*?]` in current route path.
        for (key in params) {
          if (currentPath.search(':\\b' + key + '\\b') !== -1) {
            $route.current.pathParams[key] = params[key];
          }
        }

        // Add any current route path params to passed params, if not set there already.
        for (key in $route.current.pathParams) {
          if (!(key in params)) {
            params[key] = $route.current.pathParams[key];
          }
        }

        // TODO: push state if `options.history` is truthy.
      }
      // If `options.history` is falsey, and controller is reloaded,
      // then make `$location` replace current history state, instead of pushing a new one.
      else if (!history) {
        $location.replace();
      }

      $route.updateParams(params);

      // Update current route params, so the change is reflected immediatelly,
      // and nearby replace() call work correctly.
      for (key in params) {
        $route.current.params[key] = params[key];
      }
    }

    return R;
  };

  return R;
});

Wie ist der aktuelle Status dieses Problems? Wird es im neuen Router gelöst? Pünktlich zum Release 1.4? Bald?

Ich habe das gleiche Problem, aber mit Abfragezeichenfolgenparametern. Ich möchte kein Nachladen beim Wechseln. Aber ich kann reloadOnSearch nicht deaktivieren, weil ich wissen muss, wenn der Benutzer die Abfragezeichenfolge manuell ändert! :)

Danke!

@marcalj fwiw, wir haben diese Lösung mit einem Dienst gehackt, der die URL mit der Adressleiste synchron hielt, damit wir reloadOnSearch deaktivieren und Abfrageparameter abrufen konnten. Außerdem können Benutzer über ein Lesezeichen oder einen Link direkt durch die URL navigieren.

Mit ng-router oder ui-router? Kannst du mir einen Link mit dem Code oder so schicken?

Vielleicht könnte das mit einem neuen Router gelöst werden, ich kann darauf warten, da mein Projekt noch nicht fertig ist.

Danke!

@marcalj unser Beispiel ist etwas verworren und möglicherweise veraltet, aber schauen Sie sich https://github.com/irthos/mngr/blob/master/app.js an und überprüfen Sie Zeile 10. Es verwendet unsere api.loadState-Methode, die Parameter in der . identifiziert url, um den richtigen Zustand zu erstellen.

NgSilent war für mich die Lösung.
Siehe https://github.com/garakh/ngSilent
Getestet mit ngRoute 1.3.15

Ich habe sowohl die @sergey-buturlakin- als auch die @kuchumovn-Lösung verwendet und stoße ständig auf das gleiche Problem.

Auf der fraglichen Seite (pagex) verwende ich location.skipReload und es funktioniert großartig - ich kann den Pfad immer wieder aktualisieren, ohne die Route zu ändern. Wenn ich dann einen tatsächlichen $location.path verwende, um die Route von pagex zu einem neuen Controller zu ändern, funktioniert es, aber wenn ich die Zurück-Taste drücke, um zu pagex zurückzukehren, und dann versuche, zu einer anderen Seite zu navigieren, kann ich nicht mehr meine Route mehr ändern, ohne den Browser zu aktualisieren. Gibt es einen Weg, dies zu umgehen?

+1

+1. Ich mag den Doppelpunkt-Ansatz, den Matias vorgeschlagen hat

+1

Es ist ein üblicher Anwendungsfall für Einzelseiten-Apps, die Seite bei einer Pfadänderung nicht neu zu laden.
sehr seltsam, warum es noch nicht zu eckig eingebettet ist.
erstelltes Plugin basierend auf der @EvanWinstanley- Lösung:
https://github.com/anglibs/angular-location-update

Sehen wir uns das in 1.5 noch einmal an. Es gibt eine verwandte PR unter #5860

Ich benötige die gleiche Funktion für die Aktualisierung der Abfragezeichenfolge, ohne den Routencontroller auszulösen! :)

Etwas wie: $location.searchSilent('sf', SearchFilter.getForRouteParams());

$location.path(href);
Umfang.$apply();
ist die Lösung!!
wir müssen informieren, um die Änderung mit $apply() abzuwinkeln

Dieser Thread ist seit 2 Jahren nicht mehr geöffnet, da Angular nicht benachrichtigt wurde - wir wollen einen Teil der Route ändern, ohne alles aufzurufen.

@petebacondarwin es wäre gut, nicht nur die Aktualisierung des Standortpfads ohne Neuladen, sondern auch die Aktualisierung der Pfadparameter ohne Neuladen ... wie oben implementiert https://github.com/angular/angular.js/issues/1699#issuecomment -96126887

Die Lösung von @jicasada hat bei mir

@jicasada funktioniert das mit dem ui-router? Ich habe einen Fehler mit ui-router gemeldet, bei dem reloa dOnSearch:false nicht funktioniert, wenn Eltern- und

+1

+1

Ich bestätige, dass ngSilent die Arbeit perfekt macht. Trotzdem wäre eine offizielle Lösung sehr willkommen.

Die Lösung besteht im Wesentlichen darin, $location.path() einen zusätzlichen Parameter hinzuzufügen.

app.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
    var original = $location.path;
    $location.path = function (path, reload) {
        if (reload === false) {
            var lastRoute = $route.current;
            var un = $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
                un();
            });
        }
        return original.apply($location, [path]);
    };
}]);

Und dann einfach so verwenden

$location.path('/path/that/you/need', false);

Ich sollte nur in der Lage sein, $location.replace() genau wie die Funktion window.location.replace. Das ist einfach albern, weil jedes Create in einem CRUD-Vorgang immer dieses Problem haben wird.

(und) +1

+1

Ich empfehle Ihnen, "Suchparameter" wie folgt zu verwenden:
/thing?id=1234
Konfigurieren Sie den Parameter nicht im Router-Anbieter, da die Ansicht und der Controller nicht neu geladen werden.
Wenn Sie einen Ausweis erhalten möchten
$location.search().id //1234
@cgross

Demo http://codepen.io/dolymood/details/jrEQBx/
Verwenden Sie decorator zum Dekorieren von ngViewDirective

+1

+1

+1

+1

+1

+1

+!

Genug der +1 schon :-)
Wir bekommen die Nachricht. Wir werden uns das vor Weihnachten anschauen!

Geschlossen von #15002.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen