webentwicklung-frage-antwort-db.com.de

AngularJS - UI Router - Programmgesteuertes Hinzufügen von Status

Gibt es eine Möglichkeit, nach der Modulkonfiguration programmgesteuert Zustände zu $ ​​stateProvider hinzuzufügen, z. Bedienung ?

Um dieser Frage mehr Kontext hinzuzufügen, habe ich eine Situation, in der ich zwei Ansätze wählen kann:

  1. versuchen Sie, das Neuladen auf den in der Modulkonfiguration definierten Status zu erzwingen. Das Problem besteht darin, dass für den Status reloadOnSearchfalse festgelegt ist. Wenn ich es also versuche $ state.go ('state.name', {new: param}, {reload: true}); nichts passiert, irgendwelche Ideen?

Zustandsdefinition

.state('index.resource.view', {
  url: "/:resourceName/view?pageNumber&pageSize&orderBy&search",
  templateUrl: "/resourceAdministration/views/view.html",
  controller: "resourceViewCtrl",
  reloadOnSearch: false,
})
  1. versuchen Sie, programmgesteuert Status hinzuzufügen, die von einem Dienst geladen werden müssen, damit das Routing ordnungsgemäß funktioniert. Ich würde lieber mit der ersten Option gehen, wenn möglich.
53
khorvat

Siehe -edit- für aktualisierte Informationen

Normalerweise werden Zustände während der Konfigurationsphase zum $stateProvider Hinzugefügt. Wenn Sie zur Laufzeit Zustände hinzufügen möchten, müssen Sie einen Verweis auf das $stateProvider In der Umgebung aufbewahren.

Dieser Code ist nicht getestet, sollte aber tun, was Sie wollen. Es wird ein Dienst namens runtimeStates erstellt. Sie können es in den Laufzeitcode einfügen und dann Zustände hinzufügen.

// config-time dependencies can be injected here at .provider() declaration
myapp.provider('runtimeStates', function runtimeStates($stateProvider) {
  // runtime dependencies for the service can be injected here, at the provider.$get() function.
  this.$get = function($q, $timeout, $state) { // for example
    return { 
      addState: function(name, state) { 
        $stateProvider.state(name, state);
      }
    }
  }
});

In I-Router Extras habe ich ein paar Dinge implementiert, die Future States heißen und einige der Eckfälle für Sie erledigen wie das Zuordnen von URLs zu Staaten, die noch nicht existieren. Future States zeigt auch, wie Sie den Quellcode für Laufzeitzustände verzögert laden können. Schauen Sie sich den Quellcode an, um ein Gefühl dafür zu bekommen, worum es geht.

-edit- für UI-Router 1.0+

In UI-Router 1.0 können Zustände zur Laufzeit mit StateRegistry.register und StateRegistry.deregister registriert und abgemeldet werden.

Um auf die StateRegistry zuzugreifen, geben Sie sie als $stateRegistry ein oder geben Sie $uiRouter ein und greifen Sie über UIRouter.stateRegistry .

UI-Router 1.0 enthält auch Future States (Zukünftige Zustände), mit denen das verzögerte Laden von Zustandsdefinitionen, selbst das Synchronisieren über URLs, erledigt wird.

109
Chris T

Chris T hat es geschafft! Der Anbieter ist der richtige Weg. Sie müssen es nicht auf das Fensterobjekt klopfen, sparen, besser schützen usw.

Der Querverweis auf seine Antwort mit diesem Artikel hat wirklich geholfen: http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/#provider

Die Lösung macht ein bestimmtes Modul $ stateProvider während des Konfigurationsblocks für andere Module während ihrer Ausführungsblöcke zugänglich.

In meiner Situation werden Dashboard-Status dynamisch generiert, abhängig von den Berechtigungen eines Benutzers.

Während meines Konfigurationsblocks wird mein Provider so eingestellt, dass er den stateProvider des Moduls übergibt (auf den später zugegriffen werden kann).

//in dashboard.module.js

var dashboardModule = angular.module('app.modules.dashboard',[
        'app.modules.dashboard.controllers',
        'app.modules.dashboard.services',
        'app.modules.dashboard.presentations.mileage'
    ])

    .provider('$dashboardState', function($stateProvider){
        this.$get = function(PATHS, $state){
            return {
                addState: function(title, controllerAs, templatePrefix) {
                    $stateProvider.state('dashboard.' + title, {
                        url: '/' + title,
                        views: {
                            '[email protected]': {
                                templateUrl: PATHS.DASHBOARD + (templatePrefix ? templatePrefix + '/' : '/') + title + '/' + title + '.view.html',
                                controller: controllerAs ? controllerAs : null
                            }
                        }
                    });
                }
            }
        }
    });

Dadurch wird mein Dashboard-Statusanbieter für andere Module verfügbar, anstatt ihn auf das Fenster zu legen.

Dann kann ich im Ausführungsblock (Controller) meines Benutzermoduls auf den Statusanbieter des Dashboards zugreifen und Status dynamisch einfügen.

var UserControllers = angular.module('app.modules.user.controllers', [])

.controller("UserLoginController", ["$state", "$dashboardState", function($state, $dashboardState){

    $dashboardState.addState('faq', null, 'content');

    $state.go('dashboard.faq');

}]);
14
Alex Boisselle

Ja, das ist möglich, aber da es sich um Caching-Ebenen handelt, ist es komplex. Alex Feinberg hat hier in seinem Blog eine Lösung dokumentiert:

http://alexfeinberg.wordpress.com/2014/03/08/dynamisch-bevölkerungsreich-angular-ui-router-states-from-a-service/

Das Ende des Artikels enthält ein Beispiel für das Erstellen eines Status mithilfe des stateProvider:

app.stateProvider.state(ent.lob.name.toLowerCase(), {
    url: '/' + ent.lob.name.toLowerCase(),
    controller: ent.lob.name.toLowerCase() + 'Controller',
    templateUrl: 'lobs/views/' + ent.lob.name.toLowerCase() + '.html'
});
4
Chad Robinson