2016-02-01 2 views
0

Мое угловое приложение запускается в состоянии/home (я использую ui-router), у которого есть свой собственный контроллер, в котором я вызываю фабричный метод для получения некоторых объектов json из мой API, который я разделяю благодаря этой фабрике между всем приложением. Я помещаю список, который я получаю от этого в объекте $ scope состояния/home.AngularJS: Сохранять состояние просмотра между различными видами с разными контроллерами

Что я хочу сделать, так это вызвать этот метод 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 
         }) 

ответ

2

Завод является одноэлементным, поэтому вы можете сделать одноразовую инициализацию на заводе и просто вернуть обещание от 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; 
     }); 
}); 
+0

Спасибо, что очень много! Это именно то, что я пытался сделать, не зная, как это сделать. – Nuzzob

0

Одно простое решение было бы одна дополнительная упаковка состояние:

.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..

+0

Мой вопрос здесь с готовностью упрощен: мне действительно нужно иметь отдельные контроллеры для этих двух видов, которые сложнее, чем просто дома/около :) – Nuzzob

+0

У вас все еще есть отдельные контроллеры. 'home' здесь имеет один контроллер, который будет сохраняться в обоих состояниях. 'home.index' и' home.about' могут иметь свои индивидуальные контроллеры, которые будут специфичны для этой точки зрения ('home.about' демонстрирует это здесь на самом деле). Просто переместите каждую общую часть в 'homeCtrl' и весь код, специфичный для штата, в контроллеры, специфичные для штата. – deceze

0

попробовать что-то вроде этого:

служба:

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

контроллер А и Б:

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

Второй раз, когда вы будете вызывать метод getStuffs() вы получите данные из кэша.

Смежные вопросы