AngularJS에서 뷰 간을 변경할 때 범위 모델 유지
AngularJS를 배우고 있습니다. My1Ctrl을 사용하는 / view1 , My2Ctrl을 사용하는 / view2 가 있다고 가정 해 봅시다 . 각보기마다 고유하지만 다른 형식을 가진 탭을 사용하여 탐색 할 수 있습니다.
사용자가 떠나서 view1 로 돌아올 때 view1 형식으로 입력 한 값 이 재설정되지 않도록하려면 어떻게해야합니까?
내 말은, view1에 대한 두 번째 방문은 어떻게 모델을 떠났을 때와 정확히 동일한 상태를 유지할 수 있습니까?
이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 또한 사용자가 페이지를 떠난 후 뒤로 버튼을 눌러 이전 페이지로 돌아갈 때 상태를 유지하고 싶었습니다. 내 모든 데이터를 루트 스코프에 넣는 것이 아닙니다 .
최종 결과는 각 컨트롤러에 서비스 를 제공 하는 것 입니다. 컨트롤러에는 신경 쓰지 않는 함수와 변수가 있습니다.
컨트롤러의 서비스는 의존성 주입에 의해 주입됩니다. 서비스는 싱글 톤이므로 컨트롤러의 데이터처럼 데이터가 손상되지 않습니다.
서비스에는 모델이 있습니다. 모델에만 데이터가 있으며 기능은 없습니다. 그렇게하면 JSON에서 앞뒤로 변환하여 유지할 수 있습니다. 지속성을 위해 html5 로컬 저장소를 사용했습니다.
마지막으로 내가 사용 window.onbeforeunload
하고 $rootScope.$broadcast('saveState');
있는 모든 서비스들이 자신의 상태를 저장해야하고, 알려 $rootScope.$broadcast('restoreState')
그들 (사용자 잎 페이지 및 프레스 뒤로 버튼은 각각 페이지로 반환 할 때 사용) 자신의 상태를 복원 알려.
내 userController에 대한 userService 라는 서비스 예제 :
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 예제
function userCtrl($scope, userService) {
$scope.user = userService;
}
뷰는 다음과 같이 바인딩을 사용합니다.
<h1>{{user.model.name}}</h1>
그리고 앱 모듈 에서 실행 기능 내 에서 saveState 및 restoreState 의 브로드 캐스트 를 처리합니다.
$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');
};
내가 언급했듯이 이것은이 시점에 도달하는 데 시간이 걸렸습니다. 그것은 매우 깨끗한 방법이지만 Angular에서 개발할 때 매우 일반적인 문제라고 생각하는 것을 수행하는 것은 약간의 엔지니어링입니다.
더 쉽게보고 싶지만 사용자가 페이지를 떠날 때를 포함하여 컨트롤러의 상태 유지를 처리하는 깨끗한 방법입니다.
답변에 약간 늦었지만 모범 사례로 업데이트 된 바이올린
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;
}
}
$ rootScope는 큰 전역 변수로, 일회성 또는 소규모 앱에 적합합니다. 모델 및 / 또는 동작을 캡슐화하고 다른 곳에서 재사용하려는 경우 서비스를 사용하십시오. 언급 된 OP를 Google 그룹에 추가하는 것 외에도 https://groups.google.com/d/topic/angular/eegk_lB6kVs/discussion을 참조 하십시오 .
Angular는 실제로 당신이 찾고있는 것을 제공하지 않습니다. 내가 한 것을 성취하기 위해 할 일은 다음 애드온을 사용하는 것입니다.
이 둘은 상태 기반 라우팅 및 고정 상태를 제공하며 상태 간을 탭할 수 있으며 모든 정보는 "유지 상태"범위로 저장됩니다.
ui router extras는 끈적 끈적한 상태가 어떻게 작동하는지 잘 보여줍니다 .
나는 같은 문제를 겪었다. 이것은 내가 한 일이다 : 나는 동일한 페이지에 여러 개의 뷰를 가진 SPA를 가지고있다 (아약스없이), 이것은 모듈의 코드이다 :
var app = angular.module('otisApp', ['chieffancypants.loadingBar', 'ngRoute']);
app.config(['$routeProvider', function($routeProvider){
$routeProvider.when('/:page', {
templateUrl: function(page){return page.page + '.html';},
controller:'otisCtrl'
})
.otherwise({redirectTo:'/otis'});
}]);
모든보기에 대해 하나의 컨트롤러 만 있지만 문제는 질문과 동일합니다. 컨트롤러는 항상 데이터를 새로 고칩니다.이 동작을 피하기 위해 사람들이 위에서 제안한 것을 수행하고 해당 목적을 위해 서비스를 만든 다음 전달합니다. 다음과 같이 컨트롤러에
app.factory('otisService', function($http){
var service = {
answers:[],
...
}
return service;
});
app.controller('otisCtrl', ['$scope', '$window', 'otisService', '$routeParams',
function($scope, $window, otisService, $routeParams){
$scope.message = "Hello from page: " + $routeParams.page;
$scope.update = function(answer){
otisService.answers.push(answers);
};
...
}]);
이제 내보기에서 업데이트 함수를 호출하고 값을 전달하고 모델을 업데이트 할 수 있습니다. 지속성 데이터에 html5 API를 사용할 필요가 없습니다 (이 경우 내 경우에는 다른 경우에는 html5를 사용해야 할 수도 있습니다) 로컬 스토리지 및 기타 자료와 같은 API).
서비스의 대안은 가치 저장소를 사용하는 것입니다.
내 앱의 기초에 이것을 추가했습니다.
var agentApp = angular.module('rbAgent', ['ui.router', 'rbApp.tryGoal', 'rbApp.tryGoal.service', 'ui.bootstrap']);
agentApp.value('agentMemory',
{
contextId: '',
sessionId: ''
}
);
...
그런 다음 컨트롤러에서 값 저장소를 참조합니다. 사용자가 브라우저를 닫으면 물건을 보유하고 있다고 생각하지 않습니다.
angular.module('rbAgent')
.controller('AgentGoalListController', ['agentMemory', '$scope', '$rootScope', 'config', '$state', function(agentMemory, $scope, $rootScope, config, $state){
$scope.config = config;
$scope.contextId = agentMemory.contextId;
...
여러 범위 및 해당 범위 내의 여러 변수에 사용할 수있는 솔루션
This service was based off of Anton's answer, but is more extensible and will work across multiple scopes and allows the selection of multiple scope variables in the same scope. It uses the route path to index each scope, and then the scope variable names to index one level deeper.
Create service with this code:
angular.module('restoreScope', []).factory('restoreScope', ['$rootScope', '$route', function ($rootScope, $route) {
var getOrRegisterScopeVariable = function (scope, name, defaultValue, storedScope) {
if (storedScope[name] == null) {
storedScope[name] = defaultValue;
}
scope[name] = storedScope[name];
}
var service = {
GetOrRegisterScopeVariables: function (names, defaultValues) {
var scope = $route.current.locals.$scope;
var storedBaseScope = angular.fromJson(sessionStorage.restoreScope);
if (storedBaseScope == null) {
storedBaseScope = {};
}
// stored scope is indexed by route name
var storedScope = storedBaseScope[$route.current.$$route.originalPath];
if (storedScope == null) {
storedScope = {};
}
if (typeof names === "string") {
getOrRegisterScopeVariable(scope, names, defaultValues, storedScope);
} else if (Array.isArray(names)) {
angular.forEach(names, function (name, i) {
getOrRegisterScopeVariable(scope, name, defaultValues[i], storedScope);
});
} else {
console.error("First argument to GetOrRegisterScopeVariables is not a string or array");
}
// save stored scope back off
storedBaseScope[$route.current.$$route.originalPath] = storedScope;
sessionStorage.restoreScope = angular.toJson(storedBaseScope);
},
SaveState: function () {
// get current scope
var scope = $route.current.locals.$scope;
var storedBaseScope = angular.fromJson(sessionStorage.restoreScope);
// save off scope based on registered indexes
angular.forEach(storedBaseScope[$route.current.$$route.originalPath], function (item, i) {
storedBaseScope[$route.current.$$route.originalPath][i] = scope[i];
});
sessionStorage.restoreScope = angular.toJson(storedBaseScope);
}
}
$rootScope.$on("savestate", service.SaveState);
return service;
}]);
Add this code to your run function in your app module:
$rootScope.$on('$locationChangeStart', function (event, next, current) {
$rootScope.$broadcast('savestate');
});
window.onbeforeunload = function (event) {
$rootScope.$broadcast('savestate');
};
Inject the restoreScope service into your controller (example below):
function My1Ctrl($scope, restoreScope) {
restoreScope.GetOrRegisterScopeVariables([
// scope variable name(s)
'user',
'anotherUser'
],[
// default value(s)
{ name: 'user name', email: 'user@website.com' },
{ name: 'another user name', email: 'anotherUser@website.com' }
]);
}
The above example will initialize $scope.user to the stored value, otherwise will default to the provided value and save that off. If the page is closed, refreshed, or the route is changed, the current values of all registered scope variables will be saved off, and will be restored the next time the route/page is visited.
You can use $locationChangeStart
event to store the previous value in $rootScope
or in a service. When you come back, just initialize all previously stored values. Here is a quick demo using $rootScope
.
var app = angular.module("myApp", ["ngRoute"]);
app.controller("tab1Ctrl", function($scope, $rootScope) {
if ($rootScope.savedScopes) {
for (key in $rootScope.savedScopes) {
$scope[key] = $rootScope.savedScopes[key];
}
}
$scope.$on('$locationChangeStart', function(event, next, current) {
$rootScope.savedScopes = {
name: $scope.name,
age: $scope.age
};
});
});
app.controller("tab2Ctrl", function($scope) {
$scope.language = "English";
});
app.config(function($routeProvider) {
$routeProvider
.when("/", {
template: "<h2>Tab1 content</h2>Name: <input ng-model='name'/><br/><br/>Age: <input type='number' ng-model='age' /><h4 style='color: red'>Fill the details and click on Tab2</h4>",
controller: "tab1Ctrl"
})
.when("/tab2", {
template: "<h2>Tab2 content</h2> My language: {{language}}<h4 style='color: red'>Now go back to Tab1</h4>",
controller: "tab2Ctrl"
});
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.js"></script>
<body ng-app="myApp">
<a href="#/!">Tab1</a>
<a href="#!tab2">Tab2</a>
<div ng-view></div>
</body>
</html>
'IT story' 카테고리의 다른 글
파이썬 모듈 docstring에 무엇을 넣어야합니까? (0) | 2020.06.11 |
---|---|
단일 파일 히스토리에서 문자열에 대한 Git 검색 (0) | 2020.06.11 |
“코드 생성기가 [100KB]를 초과하여 [일부 파일]의 스타일을 최적화하지 않았다”는 것은 무엇을 의미합니까? (0) | 2020.06.11 |
sql과 mysql의 차이점은 무엇입니까? (0) | 2020.06.11 |
닫고 처리-전화? (0) | 2020.06.11 |