Mevcut durumun önceki durumunu almanın bir yolu var mı?
Örneğin, mevcut durum B'den önceki önceki durumun ne olduğunu bilmek istiyorum (önceki durum A durumu olurdu).
Ui-yönlendirici github doc sayfalarında bulamıyorum.
Mevcut durumun önceki durumunu almanın bir yolu var mı?
Örneğin, mevcut durum B'den önceki önceki durumun ne olduğunu bilmek istiyorum (önceki durum A durumu olurdu).
Ui-yönlendirici github doc sayfalarında bulamıyorum.
Yanıtlar:
ui-router geçiş yaptıktan sonra önceki durumu izlemez, ancak durum değiştiğinde olay $stateChangeSuccess
yayınlanır $rootScope
.
Bu etkinlikten önceki durumu yakalayabilmeniz gerekir ( from
ayrıldığınız durumdur):
$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
//assign the "from" parameter to something
});
Yeni duruma geçmeden önce geçerli durum verilerini kaydetmek için çözümü kullanıyorum:
angular.module('MyModule')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('mystate', {
templateUrl: 'mytemplate.html',
controller: ["PreviousState", function (PreviousState) {
if (PreviousState.Name == "mystate") {
// ...
}
}],
resolve: {
PreviousState: ["$state", function ($state) {
var currentStateData = {
Name: $state.current.name,
Params: $state.params,
URL: $state.href($state.current.name, $state.params)
};
return currentStateData;
}]
}
});
}]);
$stateChangeSuccess
$stateChangeSuccess
, küresel düzeyde yapar, çoğu zaman gerçekten gerekli değildir.
$state.current
nesnesidir: {name: "", url: "^", views: null, abstract: true}
.
Okunabilirlik adına, çözümümü (stu.salsbury'nin anwser'ına dayanarak) buraya yerleştireceğim.
Bu kodu uygulamanızın soyut şablonuna ekleyin, böylece her sayfada çalışır.
$rootScope.previousState;
$rootScope.currentState;
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams) {
$rootScope.previousState = from.name;
$rootScope.currentState = to.name;
console.log('Previous state:'+$rootScope.previousState)
console.log('Current state:'+$rootScope.currentState)
});
RootScope'taki değişikliklerin kaydını tutar. Oldukça kullanışlı.
Aşağıdaki örnekte bir decorator
(yapılandırma aşamasında uygulama başına yalnızca bir kez çalışır) oluşturdum ve $state
hizmete fazladan bir özellik eklediğinden , bu yaklaşım genel değişkenlere genel değişkenler $rootscope
eklemez ve diğer servislere ekstra bir bağımlılık eklemesini gerektirmez $state
.
Örneğimde, bir kullanıcıyı zaten oturum açtığında ve oturum açtıktan sonra bir önceki "korumalı" sayfaya yönlendirmeyeceği zaman dizin sayfasına yönlendirmek gerekiyordu.
Kullandığım tek bilinmeyen hizmetler (sizin için) authenticationFactory
ve appSettings
:
authenticationFactory
sadece kullanıcı girişini yönetir. Bu durumda, kullanıcının oturum açıp açmadığını belirlemek için yalnızca bir yöntem kullanın.appSettings
her yerde dizgiyi kullanmamak için sabitlerdir. appSettings.states.login
ve appSettings.states.register
giriş ve kayıt URL'sinin durumunun adını içerir.Daha sonra herhangi bir controller
/ service
etc'de $state
servis enjekte etmeniz gerekir ve mevcut ve önceki url'ye şu şekilde erişebilirsiniz:
$state.current.name
$state.previous.route.name
Chrome konsolundan:
var injector = angular.element(document.body).injector();
var $state = injector.get("$state");
$state.current.name;
$state.previous.route.name;
Uygulama:
(Kullanıyorum angular-ui-router v0.2.17
ve angularjs v1.4.9
)
(function(angular) {
"use strict";
function $stateDecorator($delegate, $injector, $rootScope, appSettings) {
function decorated$State() {
var $state = $delegate;
$state.previous = undefined;
$rootScope.$on("$stateChangeSuccess", function (ev, to, toParams, from, fromParams) {
$state.previous = { route: from, routeParams: fromParams }
});
$rootScope.$on("$stateChangeStart", function (event, toState/*, toParams, fromState, fromParams*/) {
var authenticationFactory = $injector.get("authenticationFactory");
if ((toState.name === appSettings.states.login || toState.name === appSettings.states.register) && authenticationFactory.isUserLoggedIn()) {
event.preventDefault();
$state.go(appSettings.states.index);
}
});
return $state;
}
return decorated$State();
}
$stateDecorator.$inject = ["$delegate", "$injector", "$rootScope", "appSettings"];
angular
.module("app.core")
.decorator("$state", $stateDecorator);
})(angular);
$ StateChangeStart üzerindeki $ state'a {previous} adlı yeni bir mülk ekleyin
$rootScope.$on( '$stateChangeStart', ( event, to, toParams, from, fromParams ) => {
// Add {fromParams} to {from}
from.params = fromParams;
// Assign {from} to {previous} in $state
$state.previous = from;
...
}
Artık ihtiyacınız olan her yerde daha önce kullanabileceğiniz $ state kullanabilirsiniz
previous:Object
name:"route name"
params:Object
someParam:"someValue"
resolve:Object
template:"route template"
url:"/route path/:someParam"
Ve şu şekilde kullanın:
$state.go( $state.previous.name, $state.previous.params );
Aynı sorunla sıkışıp kaldım ve bunu yapmanın en kolay yolunu buluyorum ...
//Html
<button type="button" onclick="history.back()">Back</button>
VEYA
//Html
<button type="button" ng-click="goBack()">Back</button>
//JS
$scope.goBack = function() {
window.history.back();
};
(Daha test edilebilir olmasını istiyorsanız, $ window hizmetini kumandanıza enjekte edin ve $ window.history.back () kullanın.)
Endy Tjahjono'nun yaptıklarına benzer bir yaklaşım kullanıyorum.
Yaptığım şey, bir geçiş yapmadan önce mevcut durumun değerini kaydetmek. Bir örnek görelim; geçişi tetikleyen her şeye benzediğinde yürütülen bir fonksiyonun içinde bunu hayal edin:
$state.go( 'state-whatever', { previousState : { name : $state.current.name } }, {} );
Buradaki anahtar, params nesnesidir (duruma gönderilecek parametrelerin haritası) -> { previousState : { name : $state.current.name } }
Not: Ben sadece $ state nesnesinin name özniteliğini "kaydediyorum", çünkü devlet kaydetmek için gereken tek şey olduğunu unutmayın. Fakat bütün devlet nesnesine sahip olabiliriz.
Sonra, "ne olursa olsun" şöyle tanımlandığını belirtin:
.state( 'user-edit', {
url : 'whatever'
templateUrl : 'whatever',
controller: 'whateverController as whateverController',
params : {
previousState: null,
}
});
Burada kilit nokta params nesnesidir.
params : {
previousState: null,
}
Sonra, bu devletin içinde, önceki durumu şu şekilde alabiliriz:
$state.params.previousState.name
İşte Chris Thielen ui-router- extras'tan gerçekten şık bir çözüm : $ previousState
var previous = $previousState.get(); //Gets a reference to the previous state.
previous
, şuna benzer bir nesnedir: { state: fromState, params: fromParams }
burada fromState önceki durumdur ve fromParams önceki durum parametreleridir.
Tamam, burada partiye geç kaldığımı biliyorum, ama açısal için yeniyim. Buradaki John Papa stil rehberine uymaya çalışıyorum . Bunu tekrar kullanılabilir hale getirmek istedim, böylece bir blokta oluşturdum. İşte ben geldim:
previousStateProvider
(function () {
'use strict';
angular.module('blocks.previousState')
.provider('previousState', previousStateProvider);
previousStateProvider.$inject = ['$rootScopeProvider'];
function previousStateProvider($rootScopeProvider) {
this.$get = PreviousState;
PreviousState.$inject = ['$rootScope'];
/* @ngInject */
function PreviousState($rootScope) {
$rootScope.previousParms;
$rootScope.previousState;
$rootScope.currentState;
$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
$rootScope.previousParms = fromParams;
$rootScope.previousState = from.name;
$rootScope.currentState = to.name;
});
}
}
})();
Çekirdek modülü
(function () {
'use strict';
angular.module('myApp.Core', [
// Angular modules
'ngMessages',
'ngResource',
// Custom modules
'blocks.previousState',
'blocks.router'
// 3rd Party Modules
]);
})();
core.config
(function () {
'use strict';
var core = angular.module('myApp.Core');
core.run(appRun);
function appRun(previousState) {
// do nothing. just instantiating the state handler
}
})();
Bu kodla ilgili herhangi bir eleştiri sadece bana yardımcı olacaktır, bu yüzden lütfen bu kodu nerede geliştirebileceğimi bana bildirin.
Bu işlevselliğe ihtiyacınız varsa ve birden fazla denetleyicide kullanmak istiyorsanız, bu, rota geçmişini izlemek için basit bir hizmettir:
(function () {
'use strict';
angular
.module('core')
.factory('RouterTracker', RouterTracker);
function RouterTracker($rootScope) {
var routeHistory = [];
var service = {
getRouteHistory: getRouteHistory
};
$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
routeHistory.push({route: from, routeParams: fromParams});
});
function getRouteHistory() {
return routeHistory;
}
return service;
}
})();
Burada .module ('core') içindeki 'core', uygulamanızın / modülünüzün adı olacaktır. Hizmeti denetleyicinize bağımlı olarak talep edin, ardından denetleyicinizde şunları yapabilirsiniz:$scope.routeHistory = RouterTracker.getRouteHistory()
Ben $ rootScope önceki durumları takip , bu yüzden ihtiyaç olduğunda ben sadece aşağıdaki kod satırını arayacaktır.
$state.go($rootScope.previousState);
In App.js :
$rootScope.$on('$stateChangeSuccess', function(event, to, toParams, from, fromParams) {
$rootScope.previousState = from.name;
});
UI-Router için (> = 1.0), StateChange olayları kullanımdan kaldırıldı. Tam taşıma kılavuzu için burayı tıklayın
UI-Router 1.0 ve sonraki sürümlerinde geçerli durumun önceki durumunu almak için:
app.run(function ($transitions) {
$transitions.onSuccess({}, function (trans) {
// previous state and paramaters
var previousState = trans.from().name;
var previousStateParameters = trans.params('from');
});
});
Gerçekten basit bir çözüm sadece $ state.current.name dizesini düzenlemek ve son 've sonrasındaki her şeyi kesmek'. - ana durumun adını alırsınız. Durumlar arasında çok fazla atlarsanız bu çalışmaz, çünkü sadece geçerli yolu geriye doğru ayrıştırır. Ancak eyaletleriniz gerçekte bulunduğunuz yere karşılık geliyorsa, bu işe yarar.
var previousState = $state.current.name.substring(0, $state.current.name.lastIndexOf('.'))
$state.go(previousState)
$state.go('^')
bunu başaracak
Durumu şu şekilde döndürebilirsiniz:
$state.go($state.$current.parent.self.name, $state.params);
Bir örnek:
(function() {
'use strict'
angular.module('app')
.run(Run);
/* @ngInject */
function Run($rootScope, $state) {
$rootScope.back = function() {
$state.go($state.$current.parent.self.name, $state.params);
};
};
})();