Возьмите следующий код AngularJS:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular.js"></script>
<script src="main.js"></script>
</head>
<body ng-app="app" ng-controller="RootController as vm">
<input type="text" ng-model="vm.search" /> <br />
<component ng-repeat="i in vm.indices | filter:vm.search" index="i"></component>
</body>
</html>
main.js
const app = angular.module("app", []);
class RootController
{
constructor()
{
this.indices = [...Array(1000).keys()];
}
}
class ComponentController
{
constructor()
{
}
getMessage()
{
var startTime = Date.now();
while (Date.now() < startTime + 1) {}
return this.index;
}
}
app.controller("RootController", RootController);
app.component("component",
{
controller: ComponentController,
controllerAs: "vm",
template: `
{{vm.getMessage()}}
`,
bindings: {
index: "<"
}
}
);
Имеет следующие свойства:
- У нас есть список значений JS (массив "индексы").
- Мы
ng-repeat
над этим списком, чтобы создать список компонентов.Каждое значение в нем передается компоненту в качестве параметра. - Рендеринг компонента зависит от этого индекса, но как только он будет выполнен, его уже никогда не придется делать снова (это детерминировано с учетом индекса).
- Индексы будут отфильтрованы, но никогда не будут изменены.
- Рендеринг компонента стоит дорого.
Кажется, что когда я что-то набираю для фильтрации списка, AngularJS долженперерисовывать каждый компонент каждый раз, и это медленноТеоретически он должен просто скрывать и показывать компоненты, вызывая getMessage()
один раз для каждого компонента при загрузке страницы.Как я могу получить такое поведение?
Я попробовал однократное связывание ::
, которое ускоряет его при вводе поискового запроса, но когда я стираю запрос, он снова замедляется, так как я полагаю, что он все еще имеетвызвать getMessage()
, чтобы заново нарисовать компоненты, от которых он избавился.