在AngularJS中的视图之间切换时保持范围模型

Jer*_*eir 151 javascript angularjs

我正在学习AngularJS.假设我有/ view1使用My1Ctrl,/ view2使用My2Ctrl ; 可以导航到使用制表符,其中每个视图都有自己的简单但不同的形式.

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

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

Ant*_*ton 173

我花了一些时间来研究这样做的最佳方法.我还希望保持状态,当用户离开页面然后按下后退按钮,返回到旧页面; 而不只是将我的所有数据都放入了rootcope中.

最终结果是为每个控制器提供服务.在控制器中,如果它们被清除,您只需要不关心的函数和变量.

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

在服务中,我有一个模型.该模型只有数据 - 没有功能 - .这样它就可以从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;
}]);
Run Code Online (Sandbox Code Playgroud)

userController示例

function userCtrl($scope, userService) {
    $scope.user = userService;
}
Run Code Online (Sandbox Code Playgroud)

然后视图使用这样的绑定

<h1>{{user.model.name}}</h1>
Run Code Online (Sandbox Code Playgroud)

而在应用模块,运行函数中我处理的广播中的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');
};
Run Code Online (Sandbox Code Playgroud)

正如我所提到的,这需要一段时间才能达到这一点.这是一种非常干净的方式,但在Angular开发时,我怀疑这是一个非常常见的问题.

我希望看到更容易,但作为处理控制器状态的干净方法,包括用户离开并返回页面时.

  • 这描述了如何在页面刷新时保留数据,而不是在路由更改时如何保持数据,因此它不回答问题.此外,它不适用于不使用路由的应用程序.另外,它没有显示`sessionStorage.restoreState`设置为""true"的位置.要获得在页面刷新时保持数据的正确解决方案,请查看[此处](http://stackoverflow.com/questions/25428170/angular-restore-scope-from-sessionstorage/25430797).为了在路线改变时保持数据,请查看carloscarcamo的答案.您所需要的只是将数据放入服务中. (10认同)
  • 它确实持续存在于视图中,与您建议的方式完全相同,将其存储在服务中.有趣的是,它也会像使用window.onbeforeunload一样建议页面更改.谢谢你让我仔细检查.这个答案已经超过一年了,它似乎仍然是用角度做事的最简单的方法. (2认同)
  • 我认为角度缺乏内置的机制来处理这种常见的事情 (2认同)

Atu*_*ary 22

回答有点迟,但只是更新了一些最佳实践

的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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*cok 10

$ rootScope是一个很大的全局变量,适用于一次性或小型应​​用程序.如果要封装模型和/或行为(并可能在其他地方重复使用),请使用服务.除了提到OP的google网上论坛之外,另请参阅https://groups.google.com/d/topic/angular/eegk_lB6kVs/discussion.


Jos*_*lly 8

Angular并不能真正提供你想要的东西.我要做的就是完成你所追求的是使用以下附加内容

UI路由器UI路由器附加功能

这两个将为您提供基于状态的路由和粘滞状态,您可以在状态之间进行选项卡,所有信息将被保存为范围"保持活跃"可以这么说.

检查两者的文档,因为它非常简单,ui路由器附加功能也很好地演示了粘性状态的工作原理.


car*_*amo 6

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

我只有一个控制器用于所有视图,但是,问题与问题相同,控制器总是刷新数据,为了避免这种行为,我做了上面人们建议的,我为此创建了一个服务,然后传递它到控制器如下:

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);
    };
    ...
}]);
Run Code Online (Sandbox Code Playgroud)

现在我可以从我的任何视图调用更新函数,传递值并更新我的模型,我不需要使用html5 apis来获取持久性数据(这在我的情况下,可能在其他情况下使用html5是必要的apis喜欢localstorage和其他东西).