AngularJS:使用不同的控制器保持不同视图之间的视图状态

时间:2016-02-01 14:26:08

标签: javascript angularjs routes angular-ui-router

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

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

实际上,当我转到另一个州/大约,当我回到/ 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
                        })

3 个答案:

答案 0 :(得分:4)

工厂是单身人士,因此您可以在工厂进行一次性初始化,只需从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;
       });
});

答案 1 :(得分:1)

尝试这样的事情:

服务:

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()时,您将从缓存中获取数据。

答案 2 :(得分:0)

一个简单的解决方案是一个额外的包装状态:

 dialectMappings =
                    dialectMappingsLocator.locateDialectMappings(configuration);
            if (dialectMappings != null) {
                setMappingResources(dialectMappings.getAllMappingResources());
                AbstractDao.setDialectSettings(dialectMappings);
            }
            for(String resource : dialectMappings.getParentDialectMappings().getAllMappingResources()) {
                configuration.addResource(resource);
            }

这种方式.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状态,其控制器才会加载一次并保持活动状态。