【问题标题】:Dynamic orderBy Breaks ng-repeat in view in AngularJS动态 orderBy 在 AngularJS 中打破 ng-repeat
【发布时间】:2015-08-17 00:41:58
【问题描述】:

我在动态排序通过控制器中的服务获取的数据时遇到问题。当我进行初始搜索时,数据加载得很好,但是一旦我尝试更新 orderBy,我视图中的所有数据都会消失而不是重新排序。我在视图中显示的数据是存储到 $scope.filtered_events 的数据。此外,我的控制器通过路由器连接到模板。

搜索控制器

(function () {
    .controller("Search", function ($scope, zipcodeSvc, $filter, $http) {

        $scope.$on("search", search);
        $scope.sortBy = "date";

        function search(evt, data) {
            $scope.zip_codes = [];
            $scope.locations = null;
            $scope.response = null;
            $scope.events = null;

            zipcodeSvc.find(data.str, data.dist)
                .then(
                    function (response) {
                        $scope.locations = response;
                        for(i=0; i<$scope.locations.zip_codes.length; i++){
                          $scope.zip_codes.push($scope.locations.zip_codes[i].zip_code);
                        }
                        console.log($scope.zip_codes);


                        $http.get("api/events")
                        .success(function(response){
                          $scope.events = response;
                         //what I want to be able to dynamically order
                          $scope.filtered_events = $filter('eventsInRange')($scope.events, $scope.zip_codes);
                        });
                    },
                    function (err) {
                        console.log("error finding cities: ", err);
                    }
                )

        }
    })
    .filter("eventsInRange", function () {
      return function(events, zipcodes) {
        events_in_range = [];
        for(i=0;i < events.length; i++){
          if(zipcodes.indexOf(events[i].location.zip_code) > -1){
            events_in_range.push(events[i])
          }
        }
        return events_in_range;
      }
    });
}());

模板

<div class="container">
 <p class="bigger">Filter:</p>
 <ul class="nav nav-tabs">
  <li><a href='#' ng-click="sortBy = 'type'">Cya</a></li>
  <li><a href='#' ng-click="sortBy = 'location.name'">Location</a></li>
  <li><a href='#' ng-click="sortBy = 'date'">Date</a></li>
  <li><a href='#' ng-click="sortBy = 'created_by'">Creator</a></li>
</ul>
<div class="row">
  <div ng-repeat="cya in filtered_events | filter:cyaFilter | orderBy:sortBy" class="col-sm-4 text-center">
    <h2 class="primary"> {{ cya.type }} </h2>
    <div class="well cyas">
      <p> <span class="cya-label primary">Creator:</span> {{cya.created_by}}</p>
      <img class="img-responsive cya-pic" src="http://fpoimg.com/150x150" alt="{{cya.location}} picture">
    <div class="row">
      <div class="col-sm-6"><p> <span class="cya-label primary text-left">Date:</span><br> {{ cya.date }} </p></div>
      <div class="col-sm-6"><p> <span class="cya-label primary text-left">Time:</span><br> {{ cya.time }} </p></div>
    </div>
    <p> <span class="cya-label primary">Location:</span><br />
      {{cya.location.name }} <br />
      {{ cya.location.address }}
      <br /> {{ cya.location.city }}, {{ cya.location.state }}  {{ cya.location.zip_code }}</p>
    <button class="btn btn-primary join" ng-show="false">Join</button>
</div>
</div>
</div>
</div>

邮政编码服务

(function () {
    angular.module("app.data")
        .factory("zipcodeSvc", function ($http, $q) {
            return {
                find: findByLocation
            }

            function findByLocation(location, distance) {

                var url = "api/zipcodes?location=" + location + "&distance=" + distance;

                var defer = $q.defer();

                $http.get(url)
                    .success(function (response) {
                        defer.resolve(response);
                    })
                    .error(function (err) {
                        defer.reject(err);
                        console.log(err);
                    })
                return defer.promise;
            }
        });
}());

EDIT - 添加$scope.filtered_events的数据结构:

[
  { date: "mm/dd/yyyy", 
    location: { 
       address: "Someplace", 
       city: "Some city", 
       zip_code: "12345", 
       name: "Some Name", 
       state: "Some State"
     }, 
     time: "hh:mm AM", 
     type: "Some type", 
     created_by: "Some person" 
  }, 
  //etc
]

【问题讨论】:

  • 请展示数组filtered_events 的样子——在这样的问题中,它比看到你如何得到它更重要。如果您要对数据进行硬编码,它是否也不会过滤?
  • [ { "date": "mm/dd/yyyy", "location": { "address": "Someplace", "city": "Some city", "zip_code": "12345", "name": "Some Name", "state": "Some State" }, "time": "hh:mm AM", "type": "Some type", "created_by": "Some person" }, etc. etc. etc. ]
  • 如果我将信息直接在服务外部通过管道传输到控制器中的变量中,则该信息有效,但是一旦我将所有内容移动到一个函数中以使用该服务来获取数据,我使用的 orderBy 方法就会导致要空白的页面。如果我在成功调用$filter('orderBy')($scope.filtered_events, 'type') 中设置过滤器,它将在首次加载时正确执行 orderBy。
  • 它适用于我的异步数据:plnkr.co/edit/P348x6FIQuBDgf2sledx?p=preview。但是,我删除了 cyaFilter,因为它没有定义 - 并且可能是导致问题的原因。

标签: angularjs angularjs-scope angularjs-ng-repeat angularjs-service angularjs-orderby


【解决方案1】:

我怀疑问题是您的orderBy 过滤器没有更新您的$scope.filtered_events 绑定。直接在success 回调中添加$filter('orderBy')($scope.filtered_events, 'type') 时一切正常的原因是因为隐式调用了$scope.$apply()

要解决此问题,请在 orderBy 函数的末尾添加 $scope.$apply()

请参阅this 以获得快速解释。

【讨论】:

  • 现在在代码中,我正在更新orderBy 过滤器,方法是在ng-click 中更改我在视图sortBy 中排序的变量。所以我没有在过滤器中使用函数。我只是在这里交换一个变量&lt;div ng-repeat="cya in filtered_events | filter:cyaFilter | orderBy:sortBy" class="col-sm-4 text-center"&gt;,它最初是在控制器中设置的,但在点击时会改变,例如这里&lt;li&gt;&lt;a href='#' ng-click="sortBy = 'type'"&gt;Cya&lt;/a&gt;&lt;/li&gt; 所以我不清楚我将在哪里添加 $scope.$apply()。
猜你喜欢
  • 2017-01-12
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多