programing

각도에서 보기 간에 변경할 때 스코프 모델 유지JS

codeshow 2023. 3. 23. 22:58
반응형

각도에서 보기 간에 변경할 때 스코프 모델 유지JS

나는 AngularJs를 배우고 있다.My1Ctrl을 사용하는 /view1 My2Ctrl을 사용하는 /view2 있다고 칩시다.이러한 탭은, 각 뷰에 심플하지만 다른 형식이 있습니다.

사용자가 나갔다가 다시 view1로 돌아왔을 때 view1 형식으로 입력된 값이 리셋되지 않도록 하려면 어떻게 해야 합니까?

제 말은, 어떻게 두 번째 view1을 방문했을 때 모델을 그대로 유지할 수 있느냐는 것입니다.

나는 이것을 하는 가장 좋은 방법이 무엇인지 알아내기 위해 약간의 시간을 들였다.또한 사용자가 페이지를 떠난 후 뒤로 버튼을 눌러도 모든 데이터를 루트스코프에 넣는 것이 아니라 이전 페이지로 돌아갈 수 있도록 상태를 유지하고 싶었습니다.

최종 결과는 각 컨트롤러에 대한 서비스를 제공하는 것입니다.컨트롤러에는 함수 및 변수가 클리어되어 있으면 상관없는 기능 및 변수 및 함수는 클리어되어 있을 뿐입니다.

컨트롤러의 서비스는 의존성 주입에 의해 주입됩니다.서비스는 싱글톤이기 때문에 컨트롤러의 데이터처럼 데이터가 파괴되지 않습니다.

군대에서, 저는 모델이 있습니다.모형에만 함수가 없고 데이터만 있습니다.그러면 JSON에서 앞뒤로 변환하여 유지할 수 있습니다.지속성을 위해 html5 로컬 스토리지를 사용했습니다.

으로 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★window.onbeforeunload ★★★★★★★★★★★★★★★★★」$rootScope.$broadcast('saveState');에 상태를, 든든서서 to to to to to to to to to to to to to to to to to to to to to to to to to to to to to.$rootScope.$broadcast('restoreState')(사용자가 페이지를 나가 뒤로 버튼을 눌러 페이지로 돌아갈 때 사용) 상태를 복원하도록 사용자에게 통지합니다.

my 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>

그리고 앱 모듈에서는 실행 기능 내에서 saveStaterestoreState브로드캐스트를 처리합니다.

$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에서 개발할 때 매우 일반적인 문제라고 생각되는 작업을 수행하는 것은 상당한 엔지니어링 작업입니다.

사용자가 페이지를 나갔다가 다시 돌아올 때를 포함하여 컨트롤러 전반에서 상태를 유지하는 깔끔한 방법을 더 쉽게 확인하고 싶습니다.

답변이 조금 늦었지만 베스트 프랙티스를 갱신했습니다.

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;
    }
}

$rootScope는 큰 글로벌 변수이며 일회성이나 소규모 앱에 적합합니다.모델 및/또는 동작을 캡슐화하고 싶은 경우(다른 곳에서 재사용할 수도 있음) 서비스를 사용하십시오.OP가 언급한 Google 그룹 게시물 외에 https://groups.google.com/d/topic/angular/eegk_lB6kVs/discussion도 참조하십시오.

Angular는 개봉 후 원하는 기능을 제공하지 않습니다.당신이 원하는 것을 달성하기 위해 내가 해야 할 일은 다음과 같은 추가 기능을 사용하는 것입니다.

UI 라우터 및 UI 라우터 기타

이들 2개의 스테이트베이스 라우팅과 스틱스테이트를 제공합니다.스테이트간에 탭 할 수 있습니다.모든 정보는 스코프가 「stays alive」라고 하는 형태로 저장됩니다.

양쪽의 메뉴얼을 참조해 주세요.이것은 매우 알기 쉬우므로, ui 라우터 엑스트라에는 스틱스테이트가 어떻게 기능하는지도 잘 나타내고 있습니다.

같은 문제가 있었습니다.이렇게 했습니다.SPA는 같은 페이지에 여러 뷰가 표시되므로(Ajax 없이) 모듈의 코드는 다음과 같습니다.

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'});
}]);

모든 뷰에 대한 컨트롤러는 1개뿐이지만 문제는 컨트롤러가 항상 데이터를 새로 고치는 것과 같습니다.이 동작을 피하기 위해 저는 위의 사람들이 제안하는 것을 실행했고 그 목적을 위해 서비스를 작성한 후 다음과 같이 컨트롤러에 전달합니다.

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 apis를 사용할 필요가 없습니다(이 경우는 localstorage 등의 html5 apis를 사용할 필요가 있을지도 모릅니다).

서비스에 대한 대안으로 가치 저장소를 사용하는 것이 있습니다.

앱 베이스에 이렇게 추가했습니다.

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;
...

여러 범위 및 해당 범위 내의 여러 변수에 대해 작동하는 솔루션

이 서비스는 Anton의 답변을 기반으로 했지만 확장성이 뛰어나며 여러 범위에 걸쳐 기능하며 동일한 범위에서 여러 범위 변수를 선택할 수 있습니다.루트 경로를 사용하여 각 스코프를 인덱스하고 다음으로 스코프 변수 이름을 사용하여 한 단계 더 깊은 인덱스를 만듭니다.

다음 코드로 서비스 생성:

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;
}]);

앱 모듈의 실행 기능에 다음 코드를 추가합니다.

$rootScope.$on('$locationChangeStart', function (event, next, current) {
    $rootScope.$broadcast('savestate');
});

window.onbeforeunload = function (event) {
    $rootScope.$broadcast('savestate');
};

restoreScope 서비스를 컨트롤러에 삽입합니다(아래 예).

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' }
    ]);
}

위의 예에서는 $scope.user를 저장된 값으로 초기화합니다.초기화하지 않을 경우 기본값이 지정된 값으로 설정되고 이 값이 저장됩니다.페이지가 닫히거나 새로 고침되거나 루트가 변경된 경우 등록된 모든 범위 변수의 현재 값이 저장되며 다음 루트 또는 페이지가 방문될 때 복원됩니다.

사용할 수 있습니다.$locationChangeStart이전 값을 저장하는 이벤트$rootScope또는 서비스 중.다시 돌아오면 이전에 저장된 모든 값을 초기화하십시오.다음은 를 사용한 간단한 데모입니다.$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>

언급URL : https://stackoverflow.com/questions/12940974/maintain-model-of-scope-when-changing-between-views-in-angularjs

반응형