Подтвердить что ты не робот

AngularJS: виртуальное повторение с строкой с разной высотой

Я создаю гибридное приложение с использованием ионного и AngularJS (AngularJS-материала). Это приложение также имеет встроенный чат, построенный с помощью Node.js и socket.io.

У меня теперь проблема, когда только 200 сообщений очень медленно загружаются, чтобы загружать все сообщения (200 мс в браузере → 4 с в приложении, даже с помощью CrossWalk, а также с треком через message.id), а также вводя в текстовое поле для вставки сообщения замедляется.

У меня есть два решения для решения этой проблемы:

  • Виртуальный повтор (md-virtual-repeat)
  • Бесконечный свиток (ионно-бесконечный свиток)

1) Я думаю, что виртуальный повтор будет лучшим решением (я уже реализовал его на другой странице, и он прокручивает 1500 элементов, как прелесть), но проблема в том, что сообщения могут иметь разную высоту на основе их длин и md -виртуальные требования повторения - все элементы должны иметь одинаковую высоту для работы.

2) Итак, возможно, мы можем повернуть к методу бесконечной прокрутки, но теперь проблема заключается в том, что выполнение этого с помощью директивы ion-infin-scroll становится немного сложной, так как чат должен запускать loadMore() при достижении вершины и а не внизу.

Итак, мой вопрос: У кого-нибудь есть обходное решение, чтобы иметь гладкий/быстрый ng-repeat внутри чата или директива виртуального повтора, которая может обрабатывать разные высоты или бесконечный свиток, который работает вверху?

4b9b3361

Ответ 1

Несколько вещей, которые вы могли бы попытаться ускорить.

Можно было бы использовать что-то вроде quick-ng-repeat: https://github.com/allaud/quick-ng-repeat вместо встроенного angular js ng-repeat

Другим было бы использовать one time binding, где когда-либо можно было бы предотвратить angular от постоянного поиска изменений в течение каждого цикла дайджеста: https://docs.angularjs.org/guide/expression#one-time-binding

И, конечно, если это возможно, попробуйте воспользоваться параметром профиля инструмента Chrome, чтобы выяснить, какая из функций замедляет приложение; )

PS: Возможно, стоит проверить этот поток, чтобы увидеть, как можно реализовать обратную бесконечную прокрутку: Внедрение обратного бесконечного прокрутки с помощью ngInfiniteScroll директивы в AngularJS

Ответ 2

Эффективные списки прокрутки, такие как md-virtual-repeat или collection-repeat, должны знать высоту каждого элемента, чтобы работать. Это потому, что им нужно знать положение прокрутки, например. чтобы показать полосу прокрутки или пропустить кадры для быстрых движений вниз. Сама позиция прокрутки может быть найдена только в том случае, если вы знаете, сколько было прокручено (нам нужна высота элементов выше) и сколько осталось прокрутить (нам нужна высота элементов ниже).

Что вы можете сделать, это использовать factory для вычисления высоты каждого элемента перед введением их в цикл. Это можно сделать, создав контейнер с теми же свойствами, что и целевой контейнер (например, классы CSS), добавив вновь загруженные элементы, вычислил их высоту (используя element.offsetHeight) и удалив контейнер после.

Помните, что это довольно тяжело и, вероятно, вызовет небольшой запаздывание.

Ответ 3

Вы взглянули на React.js как на решение? Он использует виртуальную DOM, которая делает обновление длинных списков более эффективным.

Существует репозиторий с открытым исходным кодом на GitHub, который смешивает Angular и React, называется ngReact.

Обзор: http://ngreact.github.io/ngReact/

документы: http://ngreact.github.io/ngReact/docs/ngReact.html

Сделки РЕПО: https://github.com/ngReact/ngReact

Надеюсь, что это поможет.

Ответ 4

Использование отдельных связующих, таких как заклепки, может быть хорошим решением, его легко интегрировать и иметь rv-each для цикла

Ответ 5

Я думаю, что ионная директива collection-repeat может быть тем, что вы ищете.

collection-repeat позволяет приложению показывать огромные списки предметов намного больше чем ng-repeat. Он превращается в DOM только так, как многие элементы, которые в настоящее время видны. Это означает, что на экране телефона, который может поместиться восемь элементов, только восемь элементов, соответствующих текущей прокрутке позиция будет отображаться.

Ответ 6

Посмотрите angular -vs-repeat angular-vs-repeat

Демо: демо

Я использую длину строки для вычисления высоты элементов.

Это очень приблизительный метод. В нашем приложении мы знаем, что один английский символ с размером шрифта 15px будет иметь ширину около 6.7px (это прекрасно, если вы используете моноширинный шрифт, но это не наш случай). Также мы всегда знаем ширину каждого сегмента и высоту одной текстовой строки. itemHeight = commulativeTextLenght/lineWidth + paddingsOfItem; Кроме того, стирание строки может повлиять на ваш расчет. В общем, у нас был неплохой метод для вычисления высот около 8000 абзацев текста.