Angular2 *ngIf работает некорректно

В моем коде я использую *ngIf, который должен показывать только один из двух в любое время. Но проблема в том, что он показывает только второй, хотя в некоторых моментах второй не должен отображаться. Я использую цикл for для отображения всех элементов, но, как вы можете видеть на рисунке, отображается только второй элемент, хотя второй имеет значение -1. Спасибо за помощь!

Код:

<ng-template let-internship="rowData" pTemplate="body" *ngIf="favorite?.FavoritesIds.indexOf(internship?.InternshipId) === -1;"><!--TODO BRIAN ngif-->
  <a class="btn btn-default" [routerLink]="['/student/stageopdrachten', internship.InternshipId, false]"><!--Not shown TODO-->
    <i class="glyphicon"></i>Meer
  </a>
</ng-template>
<ng-template let-internship="rowData" pTemplate="body" *ngIf="favorite?.FavoritesIds.indexOf(internship?.InternshipId) !== -1;"><!--TODO BRIAN ngif-->
  <a class="btn btn-default" [routerLink]="['/student/stageopdrachten', internship.InternshipId, true]"><!--always shown-->
    <i class="glyphicon"></i>Meer{{favorite?.FavoritesIds.indexOf(internship?.InternshipId)}}
  </a>
</ng-template>

Изображение: Изображение, показывающее состояние


person BrianM    schedule 08.05.2017    source источник
comment
Плункер был бы полезен   -  person yurzui    schedule 08.05.2017
comment
Может быть, дело в типах, и вам следует заменить === и !== на == и != ?   -  person mankers    schedule 08.05.2017
comment
К сожалению, изменение его на == и != ничего не дало @mankers   -  person BrianM    schedule 08.05.2017
comment
Я бы с удовольствием, но я никогда раньше не использовал plunker, но вы можете видеть переменные. FavoritesIds — это числовой массив. @yurzui   -  person BrianM    schedule 08.05.2017


Ответы (3)


Используйте div вместо ng-template. Вы не можете использовать синтаксический сахар * с ng-template.

Структурные директивы

Звездочка — это «синтаксический сахар» для чего-то более сложного. Внутри Angular обесахаривает его в два этапа. Во-первых, он переводит *ngIf="..." в атрибут шаблона, template="ngIf ...", как здесь.

<div template="ngIf hero">{{hero.name}}</div>

Затем он переводит атрибут шаблона в элемент, обернутый вокруг основного элемента, вот так.

<ng-template [ngIf]="hero">
  <div>{{hero.name}}</div>
</ng-template>
person Daniel Cooke    schedule 08.05.2017
comment
Вы также можете использовать <ng-container> вместо <ng-template>, тогда вы можете использовать более удобный синтаксис *ngFor. - person Günter Zöchbauer; 08.05.2017
comment
@GünterZöchbauer, не могли бы вы предоставить дополнительную информацию о том, почему это работает неправильно? - person Daniel Cooke; 08.05.2017
comment
<div *ngIf="..."></div> совпадает с <ng-template [ngIf]="..."><div></div></ng-template>. Поэтому, если вы используете синтаксис *xxx, элемент <ng-template> создается неявно. С <ng-template *ngIf="..."> вы создадите <ng-template [ngIf]="..."><ng-template></ng-template></ng-template>, и ничего не будет отображаться, потому что внутренний шаблон никогда не будет отпечатан в DOM. Это то, что вы имеете в виду? - person Günter Zöchbauer; 08.05.2017
comment
Да, это то, что я имею в виду, но почему внутренний шаблон никогда не будет включен в DOM? Конечно, если условие для <ng-template *ngIf="..."> истинно, не должно иметь значения, сколько слоев ng-template вложено внутри. Например, это все равно будет отображаться, не так ли? <ng-template><ng-template>hello</ng-template></ng-template Есть ли что-то, что я упускаю из виду в природе ng-template ? - person Daniel Cooke; 08.05.2017
comment
<ng-template> сам по себе ничего не отображает, это просто контейнер. Директива NgIf с <ng-template [ngIf]="..."><ng-template>xxx</ng-template></ng-template> создаст <ng-template></ng-template>, когда выражение NgIf станет истинным, но Angular на самом деле не добавляет <ng-template> в DOM (он обрабатывает его только внутри JavaScript). Следовательно, какой-то другой компонент или директива должен будет получить этот <ng-template> и пометить xxx в DOM, но его нет, потому что NgIf заботится только о <ng-template>, к которому он применяется. - person Günter Zöchbauer; 08.05.2017

ОБНОВИТЬ

Как сказал @Daniel Cooke, я должен был использовать div, потому что шаблоны ng не работают так хорошо, когда рядом друг с другом. Скорее используйте div, и только один шаблон ng сделал это. Итак, рабочий код:

<ng-template let-internship="rowData" pTemplate="body" ><!--TODO BRIAN ngif -->
          <div *ngIf="favorite?.FavoritesIds.indexOf(internship?.InternshipId) === -1">
            <a class="btn btn-default" [routerLink]="['/student/stageopdrachten', internship.InternshipId, false]"><!--niet bestaat TODO-->
              <i class="glyphicon"></i>Meer
            </a>
          </div>
          <div *ngIf="favorite?.FavoritesIds.indexOf(internship?.InternshipId) != -1;">
            <a class="btn btn-default" [routerLink]="['/student/stageopdrachten', internship.InternshipId, true]"><!--wel bestaat-->
              <i class="glyphicon"></i>Meer{{favorite?.FavoritesIds.indexOf(internship?.InternshipId)}}
            </a>
          </div>
        </ng-template>
person BrianM    schedule 08.05.2017
comment
Используйте <ng-container> вместо <ng-template>, тогда вы сможете использовать более удобный синтаксис *ngFor - person Günter Zöchbauer; 08.05.2017
comment
Спасибо за совет, я воспользуюсь им в будущем @GünterZöchbauer - person BrianM; 08.05.2017

Сделайте {{любимый?.FavoritesIds.indexOf(стажировка?.InternshipId) | json}} чтобы увидеть, что в переменной

Мой совет — поместить оператор if в отдельную функцию.

Возможно, что === проверяет строку, а это число.

person Simon Sharp    schedule 08.05.2017
comment
ngIf должен работать с числами, я искал его, прежде чем спросить здесь - person BrianM; 08.05.2017