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

Angular Factory and Service work but not as expected

本文关键字:工厂 服务工作      更新时间:2023-09-26

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

我可以让它工作,因为我可以访问 json 数据,查找详细信息并返回对象。但是,无论我怎么做,如果我尝试返回多个对象,每种类型的业务一个,我会将所有业务放在一起或出现错误(稍后会详细介绍)。

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

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

位置.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正在进行中。我阅读了错误并了解了为什么我会得到它,但只是不确定如何修复它。

位置.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);
  });
})

所以在过去的一周里,我读了很多书,也学到了很多东西。我完全将上面的混乱重写为类似于体面代码的东西,最初有很多问题。无论如何,我让一切都正常。这是它现在的样子。

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