Как создать переменную в цикле ngFor?

Я пытаюсь выяснить, как создать переменную в ngFor loop.

У меня есть такой цикл:

<td *ngFor="#prod of products">
  <a href="{{getBuild(branch,prod)?.url}}">
    {{getBuild(branch,prod)?.status}}
   </a>
</td>

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

Есть ли способ сделать это?

Ответы

Ответ 1

Я думаю, что локальные переменные (определенные с символом #) не применяются для вашего прецедента.

Фактически, когда вы определяете локальную переменную в элементе HTML, она соответствует компоненту, если таковая имеется. Когда в элементе нет компонента, переменная относится к самому элементу.

Указание значения для локальной переменной позволяет вам выбрать определенную директиву, связанную с текущим элементом. Например:

<input #name="ngForm" ngControl="name" [(ngModel)]="company.name"/>

задает экземпляр директивы ngForm, связанной с током в переменной name.

Таким образом, локальные переменные не нацелены на то, что вы хотите, т.е. устанавливаете значение, созданное для текущего элемента цикла.

Если вы попытаетесь сделать что-то подобное:

<div *ngFor="#elt of eltList" >
  <span #localVariable="elt.title"></span>
  {{localVariable}}
</div>

У вас будет следующая ошибка:

Error: Template parse errors:
There is no directive with "exportAs" set to "elt.title" ("
  <div *ngFor="#elt of eltList" >
    <span [ERROR ->]#localVariable="elt.title"></span>
    {{localVariable}}
  </div>
"): [email protected]:10

Angular2 на самом деле ищет директиву, соответствующую указанному имени elt.title здесь)... См. этот plunkr для воспроизведения ошибки: https://plnkr.co/edit/qcMGr9FS7yQD8LbX18uY?p=preview

Для получения дополнительной информации см. эту ссылку: http://victorsavkin.com/post/119943127151/angular-2-template-syntax, раздел "Локальные переменные".

В дополнение к текущему элементу итерации ngFor предоставляет только набор экспортированных значений, которые могут быть добавлены к локальным переменным: index, last, even и odd.

Смотрите эту ссылку: https://angular.io/docs/ts/latest/api/common/NgFor-directive.html

Что вы можете сделать, так это создать дополнительный компонент для отображения элементов в цикле. Он примет текущий элемент как параметр и создаст вашу "локальную переменную" как атрибут компонента. Затем вы сможете использовать этот атрибут в шаблоне компонента, чтобы он был создан один раз для каждого элемента цикла. Вот пример:

@Component({
  selector: 'elt',
  template: `
    <div>{{attr}}</div>
  `
})
export class ElementComponent {
  @Input() element;

  constructor() {
    // Your old "localVariable"
    this.attr = createAttribute(element.title);
  }

  createAttribute(_title:string) {
    // Do some processing
    return somethingFromTitle;
  }
}

и способ его использования:

<div *ngFor="#elt of eltList" >
  <elt [element]="elt></elt>
</div>

Ответ 2

Я думаю, что это классический случай для создания подкомпонента.

<td *ngFor="#prod of products">
    <subComp [prod]=prod></subComp>
</td>

Затем ваш компонент будет иметь вход prod и запустить требуемую функцию один раз в OnInit.

Простой пример plunk здесь

Ответ 3

С угловым 4 вы можете сделать это:

<td *ngFor="#prod of products">
  <div *ngIf="getBuild(branch,prod); let build">
    <a href="{{build.url}}">
     {{build.status}}
    </a>
  </div>
</td>

Ответ 4

Нет, просто кешируйте результат в getBuild для каждой комбинации branch/prod или до тех пор, пока он вызывается с теми же значениями, что и раньше.