UI-Select和AngularJS,包含大量项目

时间:2018-03-27 15:30:28

标签: angularjs

我正在使用带有AngularJS的UI-Select来显示带有大量项目(~5k)的自动完成/下拉列表。不幸的是,UI-Select在这个项目数量方面存在很大的性能问题(打开下拉列表大约需要3秒)。我已经阅读了几种提高性能的可能性,比如设置最小输入长度,但遗憾的是它们不适合我。

我发现,当下拉菜单打开时,观察者的数量正在爆炸。我试图删除双向数据绑定,但过滤器功能不再起作用。

如何让UI-Select以可接受的性能工作,但仍然可以通过用户输入过滤项目?我也可以自由地提出其他指令的建议,这些指令正在做类似于UI-Select的事情,但在性能方面做得更好。

1 个答案:

答案 0 :(得分:2)

您可以使用其他Bootstrap UI组件来显示UI-Select等数据,

但是如果你想让它运行得更快,你需要尽量减少观察者的数量。为此,您需要删除双向数据绑定(ng-model="data"{{data}})并切换到单向数据绑定(ng-bind="data"{{::data}})。

这将阻止您使用过滤器(搜索/选择数据)。因此,解决方法是使用ng-show / ng-if来显示相关数据。这是一个例子



var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
  $scope.items = [
    {name:"adam"},
    {name:"kevin"},
    {name:"billy"},
    {name:"alice"},
    {name:"bob"}
  ]
});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">

  <input ng-model="query" />
  <h3>Two-way data-binding <small>(slow)</small></h3>
  <li ng-repeat="item in items | filter:query">
    {{item.name}}
  </li>
  <hr>
  <h3>One-way data-binding <small>(fast)</small></h3>
  <li ng-repeat="item in ::items" ng-show="([item.name] | filter:query).length">
    {{::item.name}}
  </li>

</div>
&#13;
&#13;
&#13;

以下是使用Dropdown和模板的示例:

&#13;
&#13;
var app = angular.module('myApp', ['ui.bootstrap']);
app.controller('myCtrl', function($scope) {
  $scope.items = [{
      name: "adam"
    },
    {
      name: "kevin"
    },
    {
      name: "billy"
    },
    {
      name: "alice"
    },
    {
      name: "bob"
    }
  ];
  $scope.select = function(item) {
    $scope.selected = item;
  }
});
app.directive('disableAutoClose', function() {
  return {
    link: function($scope, $element) {
      $element.on('click', function($event) {
        /* prevent closing the dropdown */
        $event.stopPropagation();
      });
    }
  };
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />

<div ng-app="myApp" ng-controller="myCtrl">

  <div class="btn-group" uib-dropdown>
    <button id="button-template-url" type="button" class="btn btn-primary" uib-dropdown-toggle>
    Select <span class="caret"></span>
  </button>
    <ul class="dropdown-menu" uib-dropdown-menu template-url="dropdown.html">
    </ul>
  </div>

  <p ng-show="selected">Selected: {{selected.name}}</p>

  <!-- Can be a different file-->
  <script type="text/ng-template" id="dropdown.html">
    <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="button-template-url">
      <li role="menuitem">
        <input disable-auto-close type="text" ng-model="query" class="form-control" placeholder="Search"></li>
      <li role="menuitem" ng-repeat="item in items | filter : query"><a href="#" ng-click="select(item)">{{item.name}}</a></li>
    </ul>
  </script>

</div>
&#13;
&#13;
&#13;