为了账号安全,请及时绑定邮箱和手机立即绑定

在AngularJS中的视图之间进行更改时,维护范围模型

/ 猿问

在AngularJS中的视图之间进行更改时,维护范围模型

不负相思意 2019-10-05 10:54:40

我正在学习AngularJS。比方说,我有/厂景使用My1Ctrl,和/视图2使用My2Ctrl ; 可以使用标签浏览,每个视图都有自己简单但不同的形式。

当用户离开然后返回到view1时,如何确保以view1形式输入的值不被重置?

我的意思是,第二次访问view1如何保持与我离开模型时完全相同的状态?


查看完整描述

3 回答

?
忽然笑

我花了一些时间来确定什么是最好的方法。我还想保留状态,即当用户离开页面然后按返回按钮返回到旧页面时;而不仅仅是将我所有的数据都放到rootscope中。


最终结果是为每个控制器提供服务。在控制器中,只要清除了函数和变量,它们就不会在乎。


控制器的服务是通过依赖项注入来注入的。由于服务是单例的,因此它们的数据不会像控制器中的数据那样被破坏。


在服务中,我有一个模型。该模型仅具有数据-无功能-。这样,可以将其从JSON来回转换以持久化它。我使用html5 localstorage进行持久化。


最后,我使用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中开发时很常见的问题的工程是相当多的工程。


我希望看到更简单但更干净的方法来处理跨控制器的保持状态,包括用户何时离开并返回页面。


查看完整回答
反对 回复 2019-10-05
?
慕尼黑8549860

答案有点晚了,但只是更新了一些最佳做法


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;

    }

}


查看完整回答
反对 回复 2019-10-05
?
料青山看我应如是

我遇到了同样的问题,这就是我所做的:我在同一个页面中有一个具有多个视图的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'});

}]);

对于所有视图,我只有一个控制器,但是问题与问题相同,控制器总是刷新数据,为了避免这种行为,我按照人们上面的建议进行了操作,并为此目的创建了一个服务,然后将其传递到控制器,如下所示:


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

    };

    ...

}]);

现在,我可以从任何视图中调用update函数,传递值并更新模型,不需要使用html5 apis来存储持久性数据(在我的情况下,也许在其他情况下使用html5像localstorage等其他API)。


查看完整回答
反对 回复 2019-10-05

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信