Эффективный способ связывания один раз, но позволяющий обновить все элементы

Давайте предположим, что список из 1000 элементов отображается с бесконечной прокруткой.

Каждый элемент отображает: имя, фамилию и настроение человека. (чтобы было проще)

Изначально я не хотел слушать обновления.
Таким образом, великолепная директива angular-bindonce или даже лучше: угловая 1.3 функция одно-связывания сделала свое дело.

Теперь я создал компонент pull-to-refresh, позволяющий обновить все элементы.
Тем не менее, как связывание один раз (и без перезагрузки страницы) весь мой список не принял во внимание обновления.

Используя angular-bindonce, у меня есть это в настоящее время:

<div bindonce ng-repeat="person in persons track by person.id">
  <span bo-text="person.firstName"></span>
  <span bo-text="person.lastName"></span>
  <span bo-text="person.currentMood"></span>
</div>

Функция "подтянуть-обновить" запускает эту функцию:

$scope.refresh() {
    Persons.getList(function(response)) {
      $scope.persons = response.data;  //data being an array
    }
}

Вопрос:

Есть ли способ обновить все данные ТОЛЬКО при срабатывании pull-to-refresh?
В этом случае я смогу сохранить эту единственную привязку, которая значительно улучшит производительность при работе с огромными списками людей.

До сих пор я вынужден.... использовать двустороннее связывание, естественный способ работы с Angular.

В более общем смысле, как обращаться с огромными списками с бесконечной прокруткой, которые необходимо обновлять только при срабатывании некоторых событий?

3 ответа

Получить Angular-Bind-Notifier.

Используйте собственные привязки (с несколько измененным синтаксисом) и настройте разметку следующим образом:

<div ng-repeat="person in persons track by person.id" bind-notifier="{ eventKey:watchedExpression }">
  <span>{{:eventKey:person.firstName}}</span>
  <span>{{:eventKey:person.lastName}}</span>
  <!-- or with ng-bind if you prefer that -->
  <span ng-bind=":eventKey:person.currentMood"></span>
</div>

Теперь, когда значение watchedExpression изменения - $broadcast будет отправлен через детскую зону, созданную bind-notifier и расскажи каждую привязку с :key:expr синтаксис для переоценки.


Если вам нужно, вы также можете отправить $broadcast вручную в следующем формате:

$scope.$broadcast('$$rebind::' + key) // where 'key' === 'eventKey' in the example above.

refresh-on директива могла бы сделать трюк, ссылку нашел ЗДЕСЬ:

<div bindonce="persons" refresh-on="'refresh'" ng-repeat="person in persons track by person.id">
  <span bo-text="person.firstName"></span>
  <span bo-text="person.lastName"></span>
  <span bo-text="person.currentMood"></span>
</div>

Вместо того, чтобы пытаться обойтись без двусторонней привязки, но при этом иметь все свои преимущества, есть более вероятное и более простое решение. Вы говорите, что есть 1000 строк, все 1000 строк с окном просмотра / видны пользователю одновременно?

Я бы предположил, что нет, поэтому я бы предложил использовать буферное представление для списка элементов. Буферизация строк будет означать, что строки, которые не видны, не имеют привязок, но все еще занимают место в DOM, поэтому полоса прокрутки всегда точна.

Одним из главных предостережений буферизации является то, что все строки должны быть одинаковой высоты, а не строки переменной высоты.

Вот несколько виртуальных директив прокрутки / буферизации, на которые стоит обратить внимание:

https://github.com/EnzeyNet/VirtualScroll

https://github.com/stackfull/angular-virtual-scroll

https://github.com/kamilkp/angular-vs-repeat

Другие вопросы по тегам