ng-repeat with include: самый эффективный способ?

Я столкнулся с проблемой производительности с Angular (Ionic), и я хотел бы знать, какой из способов решения этой проблемы будет наиболее эффективным.

Я получаю список объектов из службы, которые я должен показать в своем приложении:

  $scope.objectList = [
    {
       id: 123456,
       name: "abcdefg",
       state: [1|2|3|4|5|6|7|8...],
       ....
    },
    ....
  ];

В списке никогда не будет больше 20-25 объектов.

Проблема в том, что элементы в списке, хотя и одного типа, должны отображаться совершенно по-разному. У меня есть разные шаблоны для каждого возможного состояния, в котором может находиться объект.

Я использую ng-repeat таким образом, чтобы показать список. Список не изменится, поэтому я могу использовать одностороннюю привязку.

<div ng-repeat="obj in ::objectList track by obj.id">
   ....    
</div>

Внутри этого ng-repeat я должен включить шаблон представления каждого объекта, который меняется в зависимости от состояния объекта.

Я пробовал разные решения, но не нашел того, который существенно улучшает производительность рендеринга.

Например, я пробовал это, но я не уверен, что привязка функции к ng-include очень эффективна.

HTML:

<div ng-repeat="obj in ::objects track by obj.id">
    <div ng-include="getTemplateToInclude(obj)"></div>
</div>

JS:

$scope.getTemplateToInclude = function(obj){
    if(obj.state === 1){
        return "tmpls/template-a.html";
    }else if(obj.state === 2){
        return "tmpls/template-b.html";
    }
    ....
};

Любое предложение о том, как справиться с этой проблемой? Какой лучший способ включить эти разные шаблоны в один список?

Должен ли я использовать нотацию односторонней привязки (::) во включенных шаблонах или достаточно того, что используется в ng-repeat?

заранее спасибо


person konpai    schedule 11.05.2015    source источник
comment
Как вы на самом деле проверяете производительность? Также насколько велики эти рендереры элементов для каждого элемента? Мы говорим о нескольких вложенных div w. мало в способе связывания или они довольно сложные структуры DOM w. вложенные директивы и формы и тому подобное?   -  person jusopi    schedule 11.05.2015
comment
Вложенные элементы div представляют собой подробные представления каждого объекта, которые содержат изображение и некоторые (от 5 до 8) поля (название, описание, дату...), а также пару кнопок. DOM не так прост, как хотелось бы, заголовок абсолютно расположен над изображением с фоновым градиентом.   -  person konpai    schedule 12.05.2015


Ответы (1)


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

  • создайте единый шаблон рендерера элементов, который будет обрабатывать ваши повторяющиеся элементы
  • продолжайте использовать синтаксис track by в ретрансляторе, чтобы перерабатывать визуализаторы элементов
  • в зависимости от типа элемента используйте комбинацию ng-show и ng-hide, чтобы отобразить правильные дочерние элементы, вложенные в ваш шаблон.

    <!-- item renderer template.html -->
    <div>
       <div ng-show="item.type == 'foo'"></div> 
       <div ng-show="item.type == 'bar'"></div> 
       <div ng-show="item.type == 'baz'"></div>
    </div>
    

Создание единого шаблона в сочетании с track by в повторителе приведет к повторному использованию элементов DOM, избавляя от необходимости извлекать их из DOM, а затем вставлять новые.

Использование ng-show или ng-hide вместо ng-if основано на той же идее, что и выше. Вы переключаете видимость элементов DOM, а не уничтожаете/создаете их.

Причина, по которой я утверждаю это, заключается в том, что почти во всех связанных с производительностью настройках повторное использование или переработка объектов обычно быстрее, чем уничтожение и последующее воссоздание новых объектов. Это, безусловно, верно для Javascript, и хотя мне еще предстоит проверить эту теорию на манипулировании DOM, могу поспорить, что это тоже верно. Я делаю обоснованное предположение, но, поскольку вы используете фреймворк Ionic, это также должно повысить производительность мобильных устройств,

Просто имейте в виду, что, учитывая различные перестановки того, что вы можете показать, и количество строк данных, вы можете увидеть лишь незначительный прирост производительности. В зависимости от количества привязок внутри вашего шаблона вы можете достичь точки, когда потеря производительности для завершения цикла дайджеста Angular будет такой же, как прирост производительности от повторного использования ваших элементов DOM.

person jusopi    schedule 12.05.2015