【问题标题】:AngularJS : why after loading more data filter stop working?AngularJS:为什么加载更多数据后过滤器停止工作?
【发布时间】:2015-06-06 06:38:19
【问题描述】:

我的演示中有一个过滤器功能我将解释我的问题我有一个表,我在其中实现了无限滚动换句话说,当用户移动到底部时,它会加载更多数据。顶部有搜索输入字段。使用这我可以过滤表中的项目。但我不知道为什么它不起作用

当您第一次搜索 "ubs" 和 "ing" 时。它工作得很好。但是当您加载更多数据时,当用户滚动到底部并加载更多数据时,它会再次尝试过滤“ubs”和“ing”为什么没有给出任何结果?

<label class="item item-input">
    <img src="https://dl.dropboxusercontent.com/s/n2s5u9eifp3y2rz/search_icon.png?dl=0">
    <input type="text" placeholder="Search" ng-model="query">
  </label> 

其次,实际上我正在实现无限滚动,所以只有 100 个元素显示。我们可以搜索 2000 年的元素(我从服务中获取)并显示搜索结果的数据吗?

更新:

【问题讨论】:

  • 我会尽快更新你。但是如果你得到答案,请发布它
  • 我尝试了,但出现错误。请检查我更新的 plunker plnkr.co/edit/JSV6eIVFocJvXVgiLzL8?p=preview
  • 你能检查一下我哪里做错了吗?
  • 我认为这不是正确的解决方案..我认为我们需要不同的方式来加载数据..因为当我加载所有数据时它工作得很好。但是当我从那里使用无限滚动时正在创建问题。为什么它不是完美的解决方案,因为有时它会显示数据有时不会。我会给你举个例子,在表格中间滚动搜索文本并按 Enter。有时它会显示数据,有时不显示数据。我们可以使用其他技术吗在不挂 UI 的情况下加载 2000 个数据
  • 我在您的 plunker plnkr.co/edit/... 中发现问题 重现该问题的步骤是 1) 滚动到底部 2 或 3 最多 5 次意味着加载数据更多 5 次然后写上“组”搜索文本框或文本框上的任何内容,然后单击交叉(X)按钮,您会注意到白屏显示,但是当您触摸表格之间的任何位置时,它会显示数据,为什么会显示白屏?你发现问题了吗?滚动到底部后加载数据。大约 5 到 6 次然后写“组”然后按“十字”按钮它显示白屏为什么?

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-repeat


【解决方案1】:

这是一个 Plunker,一切都在协同工作。我已将所有部分分成单独的 JS 文件,因为它变得不守规矩:

Plunker

搜索

内置过滤器只会返回 ng-repeat 正在显示的当前视图数据的结果。因为您不会一次将所有数据加载到视图中,所以您必须创建自己的搜索功能。

在演示中,单击搜索图标以显示搜索框,然后键入您的搜索值并按 ENTER 键或单击搜索按钮返回结果。

由于您想检查用户是否按下了 ENTER,您必须将事件和查询字符串都传递给函数,这样您就可以检查输入键码。当有人单击或点击搜索按钮时,该功能也应该运行。我在输入上设置了ng-model="query",所以 query 是视图中的引用。因此,您需要将ng-click="searchInvoices($event, query)" 添加到您的搜索按钮,并将ng-keyup="searchInvoices($event, query)" 添加到输入中。最后,为了便于清除输入字段,使用ng-show="query" 添加一个在输入不为空时显示的按钮,并使用ng-click="query=null; resetGrid()" 附加一个点击事件。

将 searchInvoices 函数添加到您的控制器。它只会在查询为空(因为如果用户使用退格键清空输入时需要重置视图)或者如果用户按下 ENTER 或者如果事件是用户单击搜索按钮时的单击事件。如果查询为空,则内部 if 语句会阻止搜索运行,并且只会重置视图。如果查询不为空,则针对整个数据集构建一个匹配结果数组,用于更新视图。

最后一行将滚动位置设置为滚动视图容器的顶部。这确保用户无需单击滚动视图容器中的某个位置即可看到结果。确保您将 $ionicScrollDelegate 注入您的控制器以使其工作在您的 ion-scroll 指令上设置 delegate-handle="invoicegrid"

  $scope.searchInvoices = function(evt, queryval) {
    if (queryval.length === 0 || evt.keyCode === 13 || evt.type === 'click') {
      if (queryval.length === 0) {
        $scope.invoice_records = $scope.total_invoice_records;
      } else {
        var recordset = $scope.total_invoice_records;
        results = [];
        var recordsetLength = recordset.length;
        var searchVal = queryval.toLowerCase();
        var i, j;
        
        for (i = 0; i < recordsetLength; i++) {
          var record = recordset[i].columns;
  
          for (j = 0; j < record.length; j++) {
            var invoice = record[j].value.toLowerCase();
            if (invoice.indexOf(searchVal) >= 0) {
              results.push(recordset[i]);
            }
          }
        }
        $scope.invoice_records = results;
        $ionicScrollDelegate.$getByHandle('invoicegrid').scrollTop();
      }
    }
  };

最后,您需要修改无限滚动指令使用的 loadMore() 函数,使其在滚动搜索结果时不会尝试加载额外的数据。为此,您可以将查询传递给指令上的 loadMore,例如:on-infinite="loadMore(query)",然后在您的函数中,您可以在查询存在时运行广播事件。此外,删除 ngIf 将确保列表保持动态。

  $scope.loadMore = function(query) {
    if (query || counter >= $scope.total_invoice_records.length) {
      $scope.$broadcast('scroll.infiniteScrollComplete');
    } else {
      $scope.counter = $scope.counter + showitems;
      $scope.$broadcast('scroll.infiniteScrollComplete');
    }
  };

【讨论】:

  • 我会在 30 分钟内检查您的解决方案后告诉您
  • 用@OrenD 的解决方案更新了 Plunker:stackoverflow.com/questions/30693994/…
  • 很抱歉你的回答不正确我没有看到那个时间。你的升序和降序不能正常工作。当前它正在对当前的 50 个元素进行排序,当滚动到底部时它会加载更多的 50 个元素,但我需要它显示来自 2000 个对象的前 50 个元素。这意味着我需要在显示之前进行排序
  • 当用户单击“V”或“^”时,在此解决方案中没有给出正确的结果或不正确我得到正确的结果stackoverflow.com/questions/30693994/… 需要集成到我们的解决方案中
  • 你在 "^" 或 "V" 之后所做的只是对当前 50 个元素进行排序,这些元素在滚动后显示并加载更多数据,然后再次对 50 个元素进行排序。但我需要对第一个 2000 个对象进行排序然后显示 50 ..than 在 scroll.above 链接正常工作后加载另一个 50 但我需要与您的解决方案集成
【解决方案2】:

您在ng-repeat 中以错误的方式使用了过滤器,例如ng-repeat="column in invoice_records | filter:query" 而不是ng-repeat="column in invoice_records | query"

  <div class="row" ng-repeat="column in invoice_records |filter:query">
    <div class="col col-center brd collapse-sm" ng-repeat="field in column.columns" ng-show="data[$index].checked && data[$index].fieldNameOrPath===field.fieldNameOrPath">{{field.value}}</div>
    <div class="col col-10 text-center brd collapse-sm"></div>
  </div>

Demo Plunkr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 2017-12-02
    • 2020-03-04
    • 1970-01-01
    相关资源
    最近更新 更多