javascript - AngularJS'te görünümler arasında geçerken kapsam modelini korumak
AngularJS öğreniyorum. Diyelim ki /view1'im My1Ctrl'yi, ve /view2'im My2Ctrl'yi kullanıyor; bunlara, her bir görünümün kendi basit ama farklı formu olan sekmeler üzerinden gidilebilir.
view1 formuna girilen değerlerin, kullanıcı view1'den ayrıldıktan sonra geri döndüğünde sıfırlanmadığından nasıl emin olabilirim?
Demek istediğim, view1'i ikinci ziyaret ettiğimde modeli bıraktığım tam aynı durumda nasıl tutabilirim?
Cevap #1
Bunu yapmanın en iyi yolunu bulmak için biraz zaman harcadım. Ayrıca, kullanıcı sayfadan ayrıldığında ve ardından geri düğmesine bastığında eski sayfaya geri dönmesini sağlamak için durumu korumak istedim; ve tüm verilerimi sadece rootscope'a koymak istemedim.
Nihai sonuç, her kontrolör için bir servise sahip olmaktır. Kontrolörde, sadece temizlenip temizlenmediğini umursamadığınız fonksiyonlar ve değişkenler vardır.
Kontrolcü için servis, bağımlılık enjeksiyonu ile enjekte edilir. Servisler tekil olduğundan, verileri kontrolcüdeki veriler gibi yok edilmez.
Serviste, bir modelim var. Model sadece veriye sahip - fonksiyon yok -. Bu şekilde JSON'dan geri ve ileriye dönüştürülebilir ve saklanabilir. Kalıcılık için html5 localstorage kullandım.
Son olarak, tüm servislerin durumlarını kaydetmeleri gerektiğini bildirmek için window.onbeforeunload ve $rootScope.$broadcast('saveState'); kullandım ve durumlarını geri yüklemelerini bildirmek için $rootScope.$broadcast('restoreState') kullandım (sırasıyla kullanıcı sayfadan ayrıldığında ve geri dönmek için geri tuşuna bastığında kullanılır).
Örnek servis, userController için userService olarak adlandırıldı :
app.factory('userService', ['$rootScope', function ($rootScope) {
var service = {
model: {
name: '',
email: ''
},
SaveState: function () {
sessionStorage.userService = angular.toJson(service.model);
},
RestoreState: function () {
service.model = angular.fromJson(sessionStorage.userService);
}
}
$rootScope.$on("savestate", service.SaveState);
$rootScope.$on("restorestate", service.RestoreState);
return service;
}]);
userController örneği
function userCtrl($scope, userService) {
$scope.user = userService;
}
Görünüm daha sonra bağlamayı bu şekilde kullanır
<h1>{{user.model.name}}</h1>
Ve app module'de, run fonksiyonu içerisinde saveState ve restoreState'in yayınlanmasını yönetiyorum
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (sessionStorage.restorestate == "true") {
$rootScope.$broadcast('restorestate'); //let everything know we need to restore state
sessionStorage.restorestate = false;
}
});
//let everthing know that we need to save state now.
window.onbeforeunload = function (event) {
$rootScope.$broadcast('savestate');
};
Belirttiğim gibi, bu noktaya gelmek biraz zaman aldı. Bunu yapmanın çok temiz bir yolu, ancak Angular ile geliştirirken çok yaygın bir sorun olduğunu tahmin edeceğim bir şeyi yapmak için oldukça fazla mühendislik gerektiriyor.
Durumu kontrolcüler arasında korumanın daha kolay ama aynı zamanda temiz yollarını görmek isterim, kullanıcı sayfayı terk edip geri döndüğünde dahil.
Cevap #2
Cevap için biraz geç ama en iyi uygulamalarla birlikte fiddle'ı yeni güncelledim
jsfiddle
var myApp = angular.module('myApp',[]);
myApp.factory('UserService', function() {
var userService = {};
userService.name = "HI Atul";
userService.ChangeName = function (value) {
userService.name = value;
};
return userService;
});
function MyCtrl($scope, UserService) {
$scope.name = UserService.name;
$scope.updatedname="";
$scope.changeName=function(data){
$scope.updateServiceName(data);
}
$scope.updateServiceName = function(name){
UserService.ChangeName(name);
$scope.name = UserService.name;
}
}
Cevap #3
$rootScope büyük bir global değişkendir, bu tek seferlik işler veya küçük uygulamalar için uygundur. Modelinizi ve/veya davranışınızı kapsüllemek (ve muhtemelen başka yerlerde yeniden kullanmak) istiyorsanız bir servis kullanın. OP'nin bahsettiği Google grup gönderisine ek olarak, ayrıca şuna da bakın: https://groups.google.com/d/topic/angular/eegk_lB6kVs/discussion.
