【问题标题】:AngularJS : Keep view state between differents views with differents controllersAngularJS:使用不同的控制器保持不同视图之间的视图状态
【发布时间】:2016-02-01 14:26:08
【问题描述】:

我的 Angular 应用程序在 /home 状态下启动(我使用 ui-router),它有自己的控制器,在其中我调用工厂方法从我的 API 中获取一些 json 对象,这要归功于我之间的这个工厂整个应用程序。我将由此获得的列表放入 /home 状态的 $scope 对象中。

我要做的是只调用一次工厂的这个init方法,更好的是/home控制器只调用一次。

实际上,当我进入另一个状态,如 /about,当我回到 /home 时,再次调用 /home 控制器,工厂的 init 方法也是如此。那么如何保持初始视图状态呢?

StuffFactory.js:

app.factory('StuffFactory', function ($window, $http, $q) {

var stuffs;

return {
    initStuffsList: function () {

        return $http.get('http://myapi/stuff/init')
                .then(function (response) {

                    stuffs = (angular.fromJson(response.data.result));

                });


    },
    getStuffs: function () {
        return stuffs;
    }

};

});

homeController.js:

app.controller('homeCtrl', function ($scope,StuffFactory) {


StuffFactory.initStuffsList().then(function(){
         $scope.stuffs = StuffFactory.getStuffs();

       });

});

app.js:

        .config(['$stateProvider', '$urlRouterProvider']


            $urlRouterProvider.otherwise('/home');

            $stateProvider


                    .state('home', {
                        url: '/home',
                        templateUrl: './partials/home.html',
                        controller:homeCtrl
                        })
                        .state('about', {
                            url: '/about',
                            templateUrl: './partials/about.html',
                            controller:aboutCtrl
                        })

【问题讨论】:

    标签: javascript angularjs routes angular-ui-router


    【解决方案1】:

    工厂是一个单例,因此您可以在工厂中进行一次性初始化,并简单地从initStuffsList 返回一个承诺。现在初始化只发生一次,但您的控制器仍然可以确定它至少发生一次。

    app.factory('StuffFactory', function ($window, $http, $q) {
    
        var stuffs;
        var initialised = $http.get('http://myapi/stuff/init')
            .then(function (response) {
                 return stuffs = (angular.fromJson(response.data.result));
             });
        return {
            initStuffsList: function () {
                return initialised;
            },
            getStuffs: function () {
                return stuffs;
            }
        };
    });
    

    控制器保持不变:

    app.controller('homeCtrl', function ($scope,StuffFactory) {
    
    StuffFactory.initStuffsList().then(function(){
             $scope.stuffs = StuffFactory.getStuffs();
    
           });
    });
    

    还请注意,您可以将初始化代码中的值直接返回给控制器,因此使用我在上面插入的 return 这也可以:

    app.controller('homeCtrl', function ($scope,StuffFactory) {
    
    StuffFactory.initStuffsList().then(function(stuffs){
             $scope.stuffs = stuffs;
           });
    });
    

    【讨论】:

    • 非常感谢!这正是我在不知道如何做的情况下尝试做的。
    【解决方案2】:

    试试这样的:

    服务:

    app.factory('StuffFactory', function ($http, $q) {
    
      var _stuffs; // cache stuffs
    
      return {
        getStuffs: function () {
          if (_stuffs) {
            return $q.when(_stuffs);
          }
          return $http.get('http://myapi/stuff/init').then(function (response) {
            _stuffs = (angular.fromJson(response.data.result));
            return _stuffs;
          });
        }
      };
    });
    

    控制器 A 和 B:

    StuffFactory.getStuffs().then(function(stuffs){
      $scope.stuffs = stuffs;
    });
    

    第二次调用getStuffs()方法时,会从缓存中获取数据。

    【讨论】:

      【解决方案3】:

      一种简单的解决方案是增加一种包装状态:

      .state('home', {
          template: '<ui-view></ui-view>',
          controller: homeCtrl,
          abstract: true
      })
      .state('home.index', {
          templateUrl: './partials/home.html'
      })
      .state('home.about', {
          templateUrl: './partials/about.html',
          controller: aboutCtrl
      })
      

      这样home 是两个状态的父状态,只要您处于任何home. 状态,它的控制器只会被加载一次并保持活动状态。

      【讨论】:

      • 我的问题很乐意简化:我真的需要为这两个视图分开控制器,这比 home/about 更复杂:)
      • 您仍然可以拥有单独的控制器。 home 这里有一个控制器,它将在两种状态下持续存在。 home.indexhome.about 可以有它们各自的控制器,这些控制器将特定于该视图(home.about 实际上在这里演示了这一点)。只需将每个共享部分移动到 homeCtrl 并将所有特定于状态的代码移动到特定于状态的控制器中。
      猜你喜欢
      • 1970-01-01
      • 2015-08-18
      • 2023-03-31
      • 1970-01-01
      • 2015-01-03
      • 2019-06-05
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      相关资源
      最近更新 更多