【问题标题】:Angularjs Select option Performance Improvement - Gropup By Filter for 3000+ datasAngularjs 选择选项性能改进 - 按过滤器分组 3000+ 瓦
【发布时间】:2019-10-31 06:56:52
【问题描述】:

我有选择下拉菜单,它过滤与所选选项相对应的数据。如果未选择任何内容,则它会显示 3000 多条记录,这会使我的 UI 冻结几秒钟。但是对于其他具有数百个数据的选项切换是完美且快速的。有什么方法可以提高性能吗?

下面是下拉过滤器,citylist 是一个从服务器获取数据的数组。

Select City:<span class="float-right fa fa-window-close mb-2"
                  ng-click="sm.selectedCity=undefined;">
            </span>
<select ng-model="sm.selectedCity" >
    <option value="" selected hidden />
    <option ng-repeat="s in sm.citylist"
            ng-selected="sm.selectedCity" ng-value="">
      {{s.value}}
    </option>
</select>  

以下 UI 数据因上述所选城市选项而异。最初,没有选择为分组的 Country 对象之一获取超过 3000 个数据的选项。

下面简单解释一下 UI...sampledata 是一个从服务器填充的复杂对象。 sampledata 包含已分组的 Country 属性,可以通过单击右侧的加号/减号来折叠或展开它。基于选定的城市过滤器分组国家将改变。它适用于更少的数据。但是,如果某个国家/地区有更多数据,例如 (3000+),我的 UI 在清除过滤器时会冻结

<div ng-repeat="(key, value) in sm.sampledata | filter:{STFilter:sm.selectedCity} | filter:{someother } | filter:search.number  | orderBy:'Country' | groupBy: 'Country' track by $index">
      <div class="mb-5">
          {{ key }} ({{ value.length }})<span ng-class="sm.toggle[$index] === true ? 'fa fa-minus' : 'fa fa-plus'" ng-click="sm.toggle[$index] = !sm.toggle[$index]" class="pull-right"></span>
      </div>

      <div ng-show="sm.toggle[$index]">
          <div ng-repeat="o in value">
              //o is a complex object in which one of the object needs to be filtered based on selected option from dropdown
              <div>
                  {{o.sample1}}<span class="pull-right">{{o.sample2}}</span>
              </div>
              //Still more will come
          </div>
      </div>
      <hr />
</div>

注意:我使用的是 Angular 1.7.2 版本

【问题讨论】:

  • 可能必须为那 3000 个实现自定义 select,并在用户滚动时延迟加载。由于用户无法同时查看所有 3000 个选项,因此视图没有理由一开始就将它们全部绑定。
  • 注意: ngSelected 不与 selectngModel 指令交互,它只在元素上设置 selected 属性。如果您在选择上使用ngModel,则不应在选项上使用ngSelected,因为ngModel 将设置选择值和选定选项。 1
  • 最佳实践:如果您正在使用具有唯一标识符属性的对象,您应该通过此标识符而不是对象实例进行跟踪,例如item in items track by item.id。如果您稍后重新加载数据,ngRepeat 将不必为它已经呈现的项目重建 DOM 元素,即使集合中的 JavaScript 对象已被替换为新对象。 对于大型集合,这会显着提高渲染性能。 2
  • @georgeawg 我删除了 ng-selected 并且它与 ng-model 一起工作正常。谢谢你的建议。我已经在代码中使用了 track by。如果您滚动到上面示例代码的右侧,您可以看到它。这是实现的正确方法吗?我没有唯一 ID,因此使用了 $index。
  • 3000 个选项?甚至没有提到所有绑定都会触发的性能问题,这不是一个好的设计。您可以根据要求进行搜索输入并滑入一些建议。

标签: angularjs performance angularjs-ng-repeat angular-filters


【解决方案1】:

要提高性能,请使用ng-options 指令。

来自文档:

ngRepeatngOptions 之间进行选择

在许多情况下,ngRepeat 可以用于 &lt;option&gt; 元素而不是 ngOptions 以达到类似的结果。但是,ngOptions 提供了一些好处:

  • &lt;select&gt; 的模型通过 select 作为理解表达式的一部分进行分配的方式更加灵活
  • 通过不为每个重复实例创建新范围来减少内存消耗
  • 通过在 documentFragment 中而不是单独创建选项来提高渲染速度

具体来说,在 Chrome 和 Internet Explorer / Edge 中,使用 重复选项从 2000 个选项开始会显着减慢速度。

有关详细信息,请参阅


Select City:<span class="float-right fa fa-window-close mb-2"
                  ng-click="sm.selectedCity=null">
            </span>
<select ng-model="sm.selectedCity" 
        ng-options="s.value as s.value for s in sm.selectedCity">
</select>  

【讨论】:

  • 将 ng-repeat 更改为 ng-options 后,过滤器不起作用。它没有显示所选城市的分组国家
猜你喜欢
  • 1970-01-01
  • 2015-06-24
  • 2019-01-08
  • 2015-10-26
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 2018-08-21
相关资源
最近更新 更多