Факторинг AngularJS — как правильно использовать фабрику для запроса и обновления данных, представляющих данные

Я изо всех сил пытался понять «угловой» способ работы с использованием фабрик для представления данных ajax (я много делюсь между контроллерами, используя конфигурацию). Я провел обширное исследование, и все ответы, похоже, делятся на две категории:

  1. Используйте фабрику для представления данных, затем в контроллере извлеките данные и обновите фабрику:

{не предназначен для запуска angular

var app = angular.module('main', [])
app.factory('data', function($http){
    var data = []
    return data
})
app.controller('cntrl', [$scope, $http, data]){
    $scope.data = data
    $http.get('/data').success(
        function(idata){
            $scope.data = idata
    )
}
  1. Используйте фабрику для представления HTTP-запроса с обещанием, а затем назначьте эти данные $scope

    var app = angular.module('main', [])
    app.factory('data', function ($http, $q){
        var factory = {};
        factory.getdata = function(){
            var defer = $q.defer();
            $http.get('/data').success(function(idata) {
                defer.resolve(idata);
            })
            return defer.promise;
        }
        return factory;
    });
    app.controller('cntrl', [$scope, data]){
        $scope.data = []
        data.getdata().then(function(idata) { $scope.data = idata });
    }
    

У меня есть несколько проблем с этим, в первой категории фабрика выглядит мега-хромой и не добавляет особой ценности, и каждый контроллер должен иметь код для управления фабрикой. Со вторым контроллером фабрика очень сложна и на самом деле не хранит данные (для обмена между контроллерами), а просто представляет собой длинный способ написания http.get

Мой вопрос таков: как я могу использовать фабрику для представления своих данных и управлять манипулированием этими данными чистым способом? Я хотел бы сделать что-то вроде этого:

var app = angular.module('main',[])
app.factory('data', function($http){
     var factory = {}
     factory.data = []
     factory.initialise = function(){
         $http.get('/data').success(
              function(data){
                   factory.data = data
              }
         )
     }
     return factory
})
app.controller('cntrlA', [$scope, data]) {
    $scope.data = data.data
    $data.initialise()
}
app.controller('cntrlB', [$scope, data]) {
    $scope.data = data.data
}

person TobyGWilliams    schedule 24.04.2015    source источник


Ответы (1)


Я работаю над проектом с похожей проблемой. В итоге я использовал сервис в качестве хранилища данных. Вместо того, чтобы функция инициализации каждый раз получала свежие данные, она получает свежие данные только в том случае, если хранилище данных пусто или установлен флаг getFresh (ручное переопределение). Таким образом, каждый контроллер может вызывать одну и ту же функцию для получения данных и манипулировать ими в соответствии с потребностями контроллера, не вмешиваясь в исходные данные.

var app = angular.module('main',[])

app.factory('dataService', function($http, $q){
     var factory = {}
     factory.data = []
     factory.getFresh = false

     factory.initialise = function(){
         var deferred = $q.defer()
         if(factory.data.length===0 || factory.getFresh) {
             $http.get('/data').success(function(data){
                      factory.data = data
                      deferred.resolve(data)
             })
         }
         else{
             deferred.resolve(factory.data)
         }
         return deferred.promise
     }

     return factory
})

app.controller('cntrlA', [$scope, dataService]) {
    $scope.data = []
    dataService.initialise().then(function(data){
       $scope.data = data
    }
}

app.controller('cntrlB', [$scope, dataService]) {
    $scope.data = []
    dataService.initialise().then(function(data){
       $scope.data = data
    }
}
person Ben Felda    schedule 24.04.2015