Ionic. Return factory from data from JSON file

2019-05-31 15:48发布

问题:

I'm playing around with Ionic sample projects and am looking for a way to pull in the data from a json file rather than just the standard array that is in the project.

I have successfully modified services.js to grab the data from the JSON but my template does not get the data. I assume this is because it executes before the http request for the JSON has completed.

What do I need to do to make this work?

........
.factory('People', function($http) {
  // Might use a resource here that returns a JSON array
  var people = $http.get('../data/peopleData.json').success(function(response){
    console.log(response.people); //the data is correctly logged
    return response.people;
  });

  // var people = [{
  //   id: 0,
  //   name: 'Kassiopi'
  // }, {
  //   id: 1,
  //   name: 'Imerola Bay'
  // }];
  //original and works great
return {
    all: function() {
      return people;
    },

    get: function(personId) {
      for (var i = 0; i < people.length; i++) {
        if (people[i].id === parseInt(people)) {
          return people[i];
        }
      }
      return null;
    }
  };

In the controller:

$scope.people = People.all();

回答1:

You are not getting in controller because data is being fetched after $scope.people = People.all(); is executed as you are making async call here. So use defer from $q service of angular.

.factory('People', function($http, $q) {
     var people = function () {
        var deffered = $q.defer();
        $http({
          method: 'GET',
          url: '../data/peopleData.json'
        }).success(function (data, status, headers, config) {
          deffered.resolve(data);
        }).error(function (data, status, headers, config) {
          deffered.reject(status);
        });

        return deffered.promise;
      };

And change in factory return

  return {
    all: people,

Now people will return you promise in controller , from which you can get data this way

 var peoplePromise =  People.all();
 peoplePromise.then(function(response){
  $scope.people = response; //assign data here to your $scope object
},function(error){
  console.log(error);
})


回答2:

Basically you wanted to return data from your service Harbours, and you are using callback on the ajax and trying to return data from the callback is main threat in your current code. In your factory you need to return the $http.get function which has promise, when the ajax gets completed it does call the .then function which has response which contains data, status, headers & statusText. For accessing data you could do use response.data & do return it from the service.

Factory

.factory('Harbours', function($http) {
  // Might use a resource here that returns a JSON array
  var people = return $http.get('../data/peopleData.json').then(function(response){
    data = response.data;
    console.log(data.people); //the data is correctly logged
    return data.people;

  });

  return {
     all: function() {
        return people;
     },
     //other code here
  };
});

Your current code has $scope.people = People.all(); which is nothing but assigning People.all() which does nothing this is not how promises & async call work. You need to do follow below step and code to get your code working.

For getting access to data from a controller you need to again use .then function on your service people method which returns a promise. Basically the controller .then function will get called once the data

Controller

app.controller('myCtrl', function(Harbours, $scope){
   //this will call people of Harbours service
   //.then function will get call once the people function, 
   //resolves its promise and return a data
   Harbours.all().then(function(data){ //success callback
       console.log(data); //you will have your data here.
       $scope.people = data;
   },function(error){ //error callback
       console.log(error);//error occurred here
   })
})

I'd suggest you to read up How Promises work