2017-01-06 1 views
1

Я пытаюсь извлечь данные из внешнего файла JSON и отобразить его для просмотра пользователем. Благодаря различным действиям пользователь сможет изменить данные, возвращаемые из файла JSON, не внося эти изменения в файл (в этом примере, увеличивая значения на единицу, нажав на div). Я создал службу обещаний, которая успешно извлекает данные и отображает их. Я даже могу получить его, чтобы данные могли быть изменены в отдельных контроллерах.AngularJS Promises: Положите обещание на Factory, чтобы он был доступен по всему миру и * редактировался *

Здесь я застрял: Я не могу найти способ внести какие-либо изменения в данные в PromiseService, поэтому изменения не могут распространяться по всему миру. Как я могу сделать так, чтобы любое изменение данных обещаний на уровне контроллера отражалось в PromiseService и, таким образом, отражалось на любых привязках данных в приложении? Я новичок в обещаниях, поэтому я открыт совершенно по-другому.

Plunker

HTML:

<body ng-app="pageApp" ng-controller="pageCtrl" nd-model="items"> 
    {{items}} 
    <div class="button" ng-controller="buttonCtrl" ng-click="incrementValues()"> 
     Click to increment: 
     <br>{{items}} 
    </div> 
</body> 

PromiseService:

pageApp.factory('PromiseService', function($http) { 
    var getPromise = function() { 
     return $http.get('items.json').then(function(response) { 
      return response.data; 
     }); 
    }; 

    return { 
     getPromise: getPromise 
    }; 
}); 

Кнопка контроллера (Page Controller в Plunker):

pageApp.controller('buttonCtrl', function($scope, PromiseService) { 
    $scope.incrementValues = function() 
    { 
     PromiseService.getPromise().then(function(data) { 
      $scope.items = data; 
      for(var i = 0; i < data.items.length; i++) 
      { 
       data.items[i]['value']++; 
      } 
     }).catch(function() { 
     }); 
    }; 
}); 

incrementValu Функция es успешно работает в первый раз, но каждый последовательный щелчок перетягивает обещание и сбрасывает данные. Подводя итог: как отразить приращенные значения в PromiseService, в отличие от локальных переменных?

+0

Что вам нужно, чтобы получить данные, как только это будет сделано, обновите данные в разных контроллерах без повторного получения данных? –

+0

@ ManuelObregozo - это правильно. – ctrlawkdel

ответ

0

Ваша функция создает новый вызов $ http каждый раз, когда он вызывается, и, таким образом, возвращает новое обещание, инкапсулируя новые данные, каждый раз, когда он вызывается.

Вы должны вернуть такое же обещание каждый раз:

var thePromise = $http.get('items.json').then(function(response) { 
    return response.data; 
}); 

var getPromise = function() { 
    return thePromise; 
}; 
+0

Я обновил фабрику PromiseService, чтобы отразить ваши изменения [в этом Plunker] (http://plnkr.co/edit/FUuYfPyPDq8aCYTOydBB?p=preview). Я не знал, нужно ли его вызывать в контроллере как обещание или обычный объект; Я пробовал и то, и другое. Теперь я не могу получить данные из PromiseService. – ctrlawkdel

+0

Вам просто нужно сделать то, что я сказал в ответ: http://plnkr.co/edit/xvFAXbmiByezJQzPYGVz?p=preview –

+0

А, у меня была опечатка где-то. Спасибо, что ответили! Это прекрасно работает. – ctrlawkdel

1

Вы можете добавить в свой завод в private собственности, где вы храните предметы. Затем создайте 3 разных метода обновления и доступа к этому свойству.

pageApp.factory('PromiseService', function($http) { 
     var items = {}; // [] in case it is an array 

     var updateData = function(updatedData){ 
      items = updatedData; 
     } 

     var getUpdateData = function(){ 
      return items; 
     } 

     var getPromise = function() { 
      return $http.get('items.json').then(function(response) { 
       items = response.data; 
       return response.data; 

      }); 
     }; 

     return { 
      getPromise: getPromise, 
      updateData : updateData, 
      getUpdateData : getUpdateData 
     }; 
    }); 


pageApp.controller('buttonCtrl', function($scope, PromiseService) { 

    $scope.items = []; 

    //You should call this method to retrieve the data from the json file 
    $scope.getData = function(){ 
     PromiseService.getPromise().then(function(data) { 
      $scope.items = data;    
     }).catch(function() { 
     }); 

    } 

    $scope.incrementValues = function(){ 
     for(var i = 0; i < $scope.items.length; i++){ 
      $scope.items[i]['value']++; 
     }  
     PromiseService.updateData($scope.items); //This could be skipped in case you do not want to 'store' these changes. 
    }; 
}); 

Затем в другом контроллере можно использовать ту же самую услугу, чтобы получить updated Data так:

$scope.items = PromiService.PromiseService(); 

В будущем можно также создать новый метод для обновления самого JSON вместо хранится внутри

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