【问题标题】:Losing form input data when reinvoking a controller重新调用控制器时丢失表单输入数据
【发布时间】:2015-09-18 15:06:48
【问题描述】:

我有一个实现向导的简单多视图 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 保持最新状态的最佳方法是什么,所有更改从应用实例的生命周期一开始就进行,并且在每次视图更改时不重新实例化它?

【问题讨论】:

  • 如果你不想容器级别,你应该使用服务

标签: javascript angularjs angularjs-scope angularjs-routing angularjs-view


【解决方案1】:

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

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

angular.module('app').controller('ctrl', function(formService) {
   this.formData = formService.data;
});

【讨论】:

  • 在这种特殊情况下,如果没有明确地监听它,我应该如何捕捉视图切换事件?而如果是唯一的方式,ng-route 也没用,导航逻辑也变得太复杂了。
  • 保持路由不变,只需更改控制器以从服务中提取 formData 值。
【解决方案2】:

Angular 控制器在你的模板中有一个新的ng-controller时被实例化。

Angular 服务只实例化一次,在你第一次需要它时,因为它们是singleton

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-12
      • 1970-01-01
      • 1970-01-01
      • 2020-11-10
      • 2012-12-26
      • 1970-01-01
      相关资源
      最近更新 更多