3

我有一个实现向导的简单多视图 Angular 应用程序,因此每次用户单击“下一步”按钮时,应用程序都会导航到下一个视图,“返回”按钮也是如此。我有一个$routeProvider将所有视图绑定到同一个控制器的配置。每个视图代表一个带有输入字段的巨大表单块,并$routeProvider管理它们之间的导航:

app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
    $routeProvider.when('/salespoints', {
        templateUrl: 'salespoints',
        controller: 'main'
    })
    .when('/users', {
        templateUrl: 'users',
        controller: 'main'
    })
    .otherwise({
        templateUrl: 'partner',
        controller: 'main'
    });

    $locationProvider.hashPrefix('');
}]);

问题是,每次用户单击“下一步”或“返回”时,都会调用控制器,因此$scope对前面步骤所做的所有更改都会丢失:

app.controller('main', ['$scope', function ($scope) {
    console.log('controller invoked'); // appears each time a user presses "Next" or "Back", hence re-instantiation of $scope
}]);

该应用程序足够小,可以在所有其他方法都失败的情况下转向$rootScope,但我只是想避免将其作为反模式。

保持最新状态的最佳方式是什么$scope,从应用实例生命周期的一开始就进行所有更改,并且在每次视图更改时都不需要重新实例化它?

4

3 回答 3

5

使用服务来保存您的表单数据并将其注入您的控制器。

angular.module('app').factory('formService', function () {
   var data = {};
   return {
      data: data
   };
});

angular.module('app').controller('ctrl', function(formService) {
   this.formData = formService.data;
});
于 2015-07-01T12:46:13.930 回答
1

每当您的模板中有新的控制器时,都会实例化Angular控制器。 ng-controller

Angular服务仅在您第一次需要时实例化一次,因为它们是单例的。

因此,应该使用角度服务来存储数据,尤其是在多个控制器实例之间共享的数据(即使它与您的示例中的控制器定义相同)。

于 2015-07-01T12:48:39.203 回答
1

因此,根据@joao-leal 的建议,我将数据持久性移至新服务并通过订阅$scope更新$scope.$watch。整体解决方案产生了一个非常简单的代码块:

app.factory('formPersistence', function () {
    var data = {};

    var get = function () {
        return data;
    };

    var set = function (updated) {
        data = updated;
    }

    var reset = function () {
        data = {};
    }

    return {
        get: get,
        set: set,
        reset: reset
    };
});

app.controller('main', ['$scope', 'formPersistence', function ($scope, formPersistence) {
    $scope.data = formPersistence.get();

    $scope.$watch('data', function () {                
        formPersistence.set($scope.data);
    });
}]);
于 2015-07-01T13:24:47.933 回答