【问题标题】:query data in ngResource (angularjs) based on selected item根据所选项目在 ngResource (angularjs) 中查询数据
【发布时间】:2017-01-24 13:43:37
【问题描述】:

我正在开发一个小型应用程序,我希望仅在使用 angularjs 中的 ngResource 选择国家/地区时才呈现城市列表。现在我可以渲染国家和城市的列表,这会使我的系统变慢并且有时会冻结我的应用程序(主要是在 ios/Safari/iphone/ipad 中)。我能够在 html 中创建过滤器,但我的问题是当我第一次打开我的应用程序时首先下载城市列表然后它被过滤。我希望能够阻止 ngResource 呈现城市列表,直到选择特定国家。下面是我的代码,我希望有人能回答这个问题,因为我有很多用户抱怨他们的手机和 ipad 在下载我的应用程序时冻结。

提前致谢。

services.js:

.factory('Country', ['$resource', function($resource){
    return $resource('/api/location/countries:id/');
}])

.factory('City', ['$resource', function($resource){
    return $resource('/api/location/cities:id/');
}])

controllers.js:

$scope.countries = [];
  Country.query(function(response){
    $scope.countries = response;
  });



$scope.cities = [];
  City.query(function(response){
    $scope.cities = response;
  });

html:

<div class="form-group">
<label ng-model="country" class="formlabel col-sm-4 control-label">Country</label>        
<div class="col-sm-8 formbox" ng-model="country">
<select class="form-control" ng-model="country" ng-change="user.country=country" ng-options="country.country for country in countries track by country.id" id="country" name="userRegisterCountry" required>
<option value="">-- Choose Country --</option>
</select>
</div>

<div class="form-group">
<label ng-model="city" class="formlabel col-sm-4 control-label">City</label>
<div class="col-sm-8 formbox" ng-model="city">
<select class="form-control" ng-model="city" ng-change="user.city=city" ng-options="city.city for city in cities | filter: {country:country.id} track by city.id" id="city" name="userRegisterCity" required>
<option value="">-- Choose City --</option>
</select> 
</div> 

【问题讨论】:

    标签: javascript html ios angularjs


    【解决方案1】:

    我假设滞后来自填充 + 过滤大量城市选择列表。选择一个国家/地区后,您是否能够获取城市的子集,并且在此之前无法获取任何城市?你可以让城市选择是正常的,当一个国家被选择时,获取该国的城市,只显示城市下拉列表中的城市,没有过滤器,甚至没有过滤器。

    尝试以下方法:

    JS:

    $scope.selectCountry = function() {
      $scope.user.country = $scope.country
      MyApi.fetchCities($scope.country.id) // just an example, replace with something suitable for your case
      .then(function(cities) {
        $scope.country.cities = cities;
      })
    }
    

    HTML:

    <div class="form-group">
        <label ng-model="country" class="formlabel col-sm-4 control-label">Country</label>        
        <div class="col-sm-8 formbox" ng-model="country">
            <select class="form-control" ng-model="country" ng-change="selectCountry()" ng-options="country.country for country in countries track by country.id" id="country" name="userRegisterCountry" required>
                <option value="">-- Choose Country --</option>
            </select>
        </div>
    </div>
    
    <div class="form-group">
        <label ng-model="city" class="formlabel col-sm-4 control-label">City</label>
        <div class="col-sm-8 formbox" ng-model="city">
            <select ng-disabled="!country" class="form-control" ng-model="city" ng-change="user.city=city" ng-options="city.city for city in country.cities" id="city" name="userRegisterCity" required>
                <option value="">-- Choose City --</option>
            </select> 
        </div>
    </div> 
    

    这样,您只有有限数量的城市可以填充下拉列表,这应该会减少延迟。此外,我们摆脱了对庞大城市列表的过滤,这进一步提供了帮助。

    编辑:如果您的 API 无法按国家/地区过滤城市,则选项 2 - HTML 基本保持不变:

    $scope.countries = [];
    Country.query(function(response) {
        $scope.countries = response;
        City.query(function(cities) {
            _.forEach(cities, function(city) {
                var country = _.find($scope.countries, {id: city.country});
                country.cities = country.cities || [];
                country.cities.push(city);
            })
        });
    });
    

    在这种情况下,下拉列表也永远不会填充应该减少延迟的整个城市列表。

    【讨论】:

    • Fissio 感谢您的快速回复,我尝试了您的解决方案,但我不明白 FetchCities 的来源?对于 MyAPI,我做了 $http.get 调用我的 api 来感染所有城市,但我想这是我首先试图避免的问题。任何建议,将不胜感激。选择一个国家/地区后,您是否能够获取城市的子集,并且在此之前无法获取任何城市?这正是我想要实现的目标,但我不知道该怎么做。
    • @Hamid 如果您的 API 无法为您提供较小的城市集,您可以尝试在第一次获取城市时按国家/地区划分城市,以避免选择过多... I'会在几分钟内更新我的答案
    • @Hamid 添加了另一种解决方案 - 您可能需要对其进行一些调整,但您不应该尝试同时将所有城市都放在下拉列表中
    • Fissio,我尝试了你的第一个代码,做了一些调整以使其适合我的 api,我的代码如下: $scope.selectCountry = function(country) { $scope.user.country = $scope.country City.query({country: country.id}).$promise.then(function(cities) { $scope.country.cities = city; }) } 但是我得到两个错误,第一个错误是ities未定义,并且城市列表未过滤我得到所有城市渲染。我在这里做错什么了吗。再次感谢
    • 这样传递参数来渲染城市:/api/location/cities/?country=1" .
    猜你喜欢
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 2015-08-22
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    相关资源
    最近更新 更多