我有一个实现向导的简单多视图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
处于最新状态的最佳方法是什么,所有更改都是从应用实例的生命周期的最初阶段开始的,而不是在每次更改视图时重新实例化它?
答案 0 :(得分:5)
使用服务保存表单数据并将其注入控制器。
angular.module('app').factory('formService', function () {
var data = {};
return {
data: data
};
});
angular.module('app').controller('ctrl', function(formService) {
this.formData = formService.data;
});
答案 1 :(得分:1)
ng-controller
时, 控制器都会实例化。
Angular 服务仅在您第一次需要时实施,因为它们是单身。
因此,角度服务应该用于存储数据,尤其是在多个控制器实例之间共享的数据(即使它与您的示例中的控制器定义相同)。
答案 2 :(得分:1)
因此,根据the advice of @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);
});
}]);