角度工厂和服务工作但不如预期

时间:2016-03-07 21:44:19

标签: javascript angularjs ionic-framework factory angular-services

我的应用正在查找谷歌的地方详细信息并显示一些信息。我有一个按照建立类型细分的json文件中的地址ID列表。工厂访问并向控制器提供ID。我还有一个循环遍历所有id的服务,查找细节并将它们添加到控制器可用的对象中。

我可以让它工作,我可以访问json数据,查找详细信息并返回对象。但是,无论我怎么做,如果我尝试返回多个对象,每个类型的业务一个,我将所有业务放在一起或一个错误(更多关于它在一分钟内)。

我已经通过多种方式构建了这个方法,但我将展示我尝试过的两种方法的代码。我是Angular的新手,所以我可能完全错了,甚至没有正确使用服务和工厂,所以请放轻松我。

locations.json

{
  "restaurants": {
    "Michaels": "ChIJwaTJAL4n5IgRgyJupbpQhjM",
    "Collage": "ChIJw5HgNzAm5IgRqbkEqKXIpC4",
    "Scarlet": "ChIJT9ImkZUn5IgREb1hYwKA1Nc",
    "Maya": "ChIJofgqBJYn5IgRVa-HQvp6KDk",
    "Ice": "ChIJnXpQpewn5IgR7k9yxWXUu1M",
    "Sangrias": "ChIJITcc_ZUn5IgR90iEna6FRGM",
    "Columbia": "ChIJ8xR18JUn5IgRfwJJByM-quU",
    "Harrys": "ChIJ8aLBaJYn5IgR60p2CS_RHIw"
  },
  "bars":
    {
      "Scarlet": "ChIJT9ImkZUn5IgREb1hYwKA1Nc",
      "Lion": "ChIJqVCL_b0n5IgRpVR5CFZWi4o",
      "Tradewinds": "ChIJpwF4ZJYn5IgRTDzwBWvlSIE",
      "Ice": "ChIJnXpQpewn5IgR7k9yxWXUu1M",
      "Stogies": "ChIJlwkiApYn5IgR6XVFMyqLAS4",
      "Rondeazvous": "ChIJkz3V7pUn5IgRQhui26imF1k",
      "Meehan": "ChIJK8NZGZYn5IgRA91RrGETwrQ",
      "Sangrias": "ChIJITcc_ZUn5IgR90iEna6FRGM",
      "NoName": "ChIJA-VeCb4n5IgRmbuF8wdOGaA",
      "StGeorge": "ChIJ4yo36JUn5IgRXgiRD7KMDe0"
    }
}

方法1

locations.js

angular.module('app.locations', [])
  .factory('restsFact', function($http){
    var restaurants = [];

    return {
      getRests: function(){
        return $http.get('locations.json').then(function(response){
          restaurants = response.data.restaurants;
          return restaurants;
        });
      }
    };
  })
  .factory('barsFact', function($http){
    var bars = [];

    return {
      getBars: function() {
        return $http.get('locations.json').then(function(response){
          bars = response.data.bars;
          return bars;
        });
      }
    };
  })
  .service('locationsService', function (ngGPlacesAPI) {
    var x, id, details, push,  placeDetails = [];

    // Takes list of specific type of locations as argument and looks up Place details for each location
    this.details = function(type) {
      for (x in type) {
        if (type.hasOwnProperty(x)) {
          id = type[x];
          ngGPlacesAPI.placeDetails({placeId: id}).then(push);
        }
      }
      return placeDetails;
    };

    push = function (data) {
      details = data;
      placeDetails.push(details);
    };

  });

控制器

.controller('RestCtrl', function($scope, locationsService, restsFact) {

  // Location Details Object
  restsFact.getRests().then(function(locs){
    $scope.restaurants= locationsService.details(locs);
  });

})

//
// Bar Controller
//
.controller('BarsCtrl', function($scope, locationsService, barsFact){

  // Locations Details Object
  barsFact.getBars().then(function(locs){
    $scope.bars = locationsService.details(locs);
  });

})

方法2

使用这种方法我可以加载一个页面,但是如果我移动到下一个页面,我会收到一个错误:[$ rootScope:inprog] $ digest已经在进行中。我读到了这个错误,并了解了为什么我会这样做,但只是不确定如何修复它。

locations.js

angular.module('app.locations', [])
  .factory('locationsFact', function($http){
    var locations = [];

    return {
      getlocations: function(){
        return $http.get('locations.json').then(function(response){
          locations = response;
          return locations;
        });
      }
    }
  })
  .service('locationsService', function (ngGPlacesAPI) {
    var x, id, details, push,  placeDetails = [];

    // Takes list of specific type of locations as argument and looks up Place details for each location
    this.details = function(type) {
      for (x in type) {
        if (type.hasOwnProperty(x)) {
          id = type[x];
          ngGPlacesAPI.placeDetails({placeId: id}).then(push);
        }
      }
      return placeDetails;
    };

    push = function (data) {
      details = data;
      placeDetails.push(details);
    };

  });

控制器

.controller('locationsCtrl', function($scope, locationsService, locationsFact){

  // Locations Details Object
  locationsFact.getlocations().then(function(locs){
    $scope.restaurants = locationsService.details(locs.data.restaurants);
    $scope.bars = locationsService.details(locs.data.bars);
  });

})

1 个答案:

答案 0 :(得分:0)

所以我在上周阅读了很多内容,并学到了很多东西。我完全将上面的内容改写成类似代码的内容,最初有很多问题。无论如何,我把一切都搞定了。以下是它现在的样子。

工厂

angular.module('app.factories', [])

  .factory('data', function($http){
    // Get JSON With Place ID's and create array of
    // place id objects for each category
    var places = {};

    places.ids = function(){
      return $http.get('locations.json')
        .success(function(data){
          places.rests = data.restaurants;
          places.bars = data.bars;
          places.lodg = data.lodging;
          places.att = data.attractions;
        });
    };
    return places;
  })

  .factory('details', function(ngGPlacesAPI, $q){
    var details = {};

    // Split ID Array into array of arrays <= 10.
    // Google won't return more than 10 details request at one time.
    details.process = function(type) {
      var idSets = {},
          size = 10,
          i, j, k;

      for (i=0, j=type.length, k=0; i<j; i+=size){
        idSets[k] = type.slice(i, i+size);
        k++;
      }
      return idSets;
    };

    // Lookup Details by Place ID
    // Loop through ID array and return array of details objects
    details.getDetails = function(idSet, pageNum) {
      var page = idSet[pageNum],
          promises = [];

      for(var i=0; i<page.length; i++) {
        promises.push(ngGPlacesAPI.placeDetails({placeId: page[i][i]}));
      }
      return $q.all(promises);
    };

    // Return Details Object
    return details;
  });

<强>控制器

//
// Restaurants Controller
//
.controller('restaurantsCtrl', function(details, data, $scope) {
  var vm = this;

  // Get JSON file with placeIds and set some variables
  data.ids().then(function() {
    var page = details.process(data.rests),
        pageNum = 0,
        numPages = page.length;
    vm.moreData = true;


    // Loads more place details on scroll down
    vm.loadMore = function() {
      if (pageNum <= numPages - 1) {
        pageNum++;
        details.getDetails(page, pageNum).then(function(response) {
          vm.rests.push(response);
          vm.$broadcast('scroll.infiniteScrollComplete');
        });
      }else{vm.moreData=false}
    };

    // Load first page of place details
    details.getDetails(page, pageNum).then(function(response){
      vm.rests = response;
      console.log(vm.rests);
    });

    // Watches for when to load more details
    $scope.$on('$stateChangeSuccess', function(){
      vm.loadMore();
    });

  });
})