programing

동일한 요소에서 *ngIf 및 *ngFor로 인해 오류 발생

linuxpc 2023. 4. 26. 23:03
반응형

동일한 요소에서 *ngIf 및 *ngFor로 인해 오류 발생

Angular's를 사용하는 데 문제가 있습니다.*ngFor그리고.*ngIf동일한 요소에

집을반 할때고의 할 때*ngFor은 컬션은다같습다니과음렉▁as▁seen로 보입니다.null결과적으로 템플릿에서 속성에 액세스하려고 하면 실패합니다.

@Component({
  selector: 'shell',
  template: `
    <h3>Shell</h3><button (click)="toggle()">Toggle!</button>

    <div *ngIf="show" *ngFor="let thing of stuff">
      {{log(thing)}}
      <span>{{thing.name}}</span>
    </div>
  `
})

export class ShellComponent implements OnInit {

  public stuff:any[] = [];
  public show:boolean = false;

  constructor() {}

  ngOnInit() {
    this.stuff = [
      { name: 'abc', id: 1 },
      { name: 'huo', id: 2 },
      { name: 'bar', id: 3 },
      { name: 'foo', id: 4 },
      { name: 'thing', id: 5 },
      { name: 'other', id: 6 },
    ]
  }

  toggle() {
    this.show = !this.show;
  }

  log(thing) {
    console.log(thing);
  }

}

쉬운 해결책은 다음 단계로 이동하는 것입니다.*ngIf레벨은 올라가지만 목록 항목을 루프오버하는 것과 같은 시나리오의 경우ul나는 결국 빈털터리가 될 것입니다.li 있는 경우 my 컬션이비경우또는내는있어렉▁the내는▁if또ion.li중복 컨테이너 요소로 감싸여 있습니다.

plnkr의 예입니다.

콘솔 오류를 기록합니다.

EXCEPTION: TypeError: Cannot read property 'name' of null in [{{thing.name}} in ShellComponent@5:12]

제가 잘못한 건가요, 아니면 버그인가요?

Angular v2는 동일한 요소에 대해 둘 이상의 구조 지시문을 지원하지 않습니다.
해결 방법으로 각 구조 지시사항에 대해 별도의 요소를 사용할 수 있는 요소를 사용하지만 DOM에 스탬프로 표시되지는 않습니다.

<ng-container *ngIf="show">
  <div *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </div>
</ng-container>

<ng-template>(<template> Angular 하지만 더 권장되지 하게 할 수 있습니다.

<ng-template [ngIf]="show">
  <div *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </div>
</ng-template>

모든 사람들이 지적했듯이, 단일 요소에 여러 개의 템플릿 지시어가 각도 1.x에서 작동하지만 각도 2에서는 허용되지 않습니다. 자세한 내용은 여기에서 확인할 수 있습니다. https://github.com/angular/angular/issues/7315

2016 각도 2 베타

은 해책은사것다입니는하를 입니다.<template>로서, 와 같이 됩니다.

<template *ngFor="let nav_link of defaultLinks"  >
   <li *ngIf="nav_link.visible">
       .....
   </li>
</template>

그러나 위의 어떤 이유로 인해 작동하지 않습니다.2.0.0-rc.4그런 경우에 당신은 이것을 사용할 수 있습니다.

<template ngFor let-nav_link [ngForOf]="defaultLinks" >
   <li *ngIf="nav_link.visible">
       .....
   </li> 
</template>

업데이트된 답변 2018

지금 당장 2018년 각진 v6 업데이트를 사용할 것을 권장합니다.<ng-container><template>

그래서 여기 업데이트된 답변이 있습니다.

<ng-container *ngFor="let nav_link of defaultLinks" >
   <li *ngIf="nav_link.visible">
       .....
   </li> 
</ng-container>

@Zyzle이 언급했듯이, @Gunter는 코멘트(https://github.com/angular/angular/issues/7315), 에서 언급했습니다. 이것은 지원되지 않습니다.

와 함께

<ul *ngIf="show">
  <li *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </li>
</ul>

빈 없 습 니 다곳은 없습니다.<li>요소를 선택합니다. 지어는심도.<ul>요소가 존재하지 않습니다(예상대로).

목록이 채워지면 중복 컨테이너 요소가 없습니다.

@Zyzle이 그의 논평에서 언급한 Github 토론(4792)은 또한 다음을 사용하는 또 다른 해결책을 제시합니다.<template>는 (으)를 사용하여 의 원래 마크업을하고 있습니다.<div>

<template [ngIf]="show">
  <div *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </div>
</template>

또한 이 솔루션은 여분/중복 컨테이너 요소를 도입하지 않습니다.

html:

<div [ngClass]="{'disabled-field': !show}" *ngFor="let thing of stuff">
    {{thing.name}}
</div>

CSS:

.disabled-field {
    pointer-events: none;
    display: none;
}

나는 이것으로 나의 문제를 해결합니다.

<ng-container *ngFor="let item of menuItems">
  <li *ngIf="canShowItem(item)"></li>
</ng-container>

할 수 .Structural Directive동일한 요소의 각도에서, 그것은 나쁜 혼란과 구조를 만들기 때문에, 당신은 그것들을 두 개의 별도의 중첩된 요소에 적용해야 합니다.ng-container), Angular 팀의 다음 문장을 읽습니다.

호스트 요소당 하나의 구조 지시문

언젠가는 HTML 블록을 반복하고 싶지만 특정 조건이 참일 때만 가능합니다.*ngFor *ngIf를 모두 동일한 호스트 요소에 배치하려고 합니다.앵귤러는 못 해요.요소에는 구조 지시문을 하나만 적용할 수 있습니다.

그 이유는 단순하기 때문입니다.구조 지시어는 호스트 요소와 그 하위 요소로 복잡한 작업을 수행할 수 있습니다.두 개의 지시어가 동일한 호스트 요소에 대한 클레임을 제기할 때, 어느 것이 우선합니까?NgIf와 NgF 중 어느 것이 먼저 해야 합니까?NgFor의 효과를 NgIf가 취소할 수 있습니까?만약 그렇다면(그리고 그렇게 되어야 할 것으로 보인다), Angular는 다른 구조적 지시에 대해 취소할 수 있는 기능을 어떻게 일반화해야 합니까?

이 질문들에 대한 쉬운 답은 없습니다.여러 개의 구조 지시를 금지하면 문제가 발생하지 않습니다.이 사용 사례에 대한 쉬운 해결책이 있습니다. *ngFor 요소를 감싸는 컨테이너 요소 에 *ngIf를 놓습니다.요소 중 하나 또는 둘 다 ng-container일 수 있으므로 HTML의 추가 수준을 도입할 필요가 없습니다.

사용할 수 있습니다.ng-container됨) 다음과 같은 이 있는 스팬으로 (Angular4)를 지정합니다.

<div class="right" *ngIf="show">
  <div *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </div>
</div>

이것은 작동하지만 요소는 DOM에 계속 남아 있습니다.

.hidden {
    display: none;
}

<div [class.hidden]="!show" *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
</div>

당신은 가질 수 없습니다.ngFor그리고.ngIf동일한 요소에사용 중인 어레이를 채우는 것을 보류할 수 있습니다.ngFor예에서 토글을 클릭할 때까지 선택합니다.

다음은 기본적인(별로) 방법입니다.

템플릿 대신 를 사용할 수도 있습니다.*ngForngIf를 동일한 HTML 요소에 모두 적용하는 경우 템플릿 태그 사용 시 주의 사항을 참조하십시오.다음은 각도 테이블에서 동일한 tr 요소에 대해 *ngIf 및 *ngFor를 모두 사용할 수 있는 예입니다.

<tr *ngFor = "let fruit of fruiArray">
    <ng-template [ngIf] = "fruit=='apple'>
        <td> I love apples!</td>
    </ng-template>
</tr>

fruiArray = ['apple', 'banana', 'mango', 'pineapple'].

참고:

용시주점은할의사▁▁just만 사용할 때의 template태그 대신 태그는 던지는 것입니다.StaticInjectionError어떤 곳에서는

포장을 하고 싶지 않았습니다.*ngFor다른 것으로div와 함께*ngIf또는 사용[ngClass]그래서 나는 이름이 붙은 파이프를 만들었습니다.show:

show.pipe

export class ShowPipe implements PipeTransform {    
  transform(values: any[], show: boolean): any[] {
    if (!show) {
      return[];
    }
    return values;
  }
}

any.page.sys

<table>
  <tr *ngFor="let arr of anyArray | show : ngIfCondition">
    <td>{{arr.label}}</td>
  </tr>
</table>

아래 표에는 "시작" 값이 설정된 항목만 나열되어 있습니다.둘 다 필요합니다.*ngFor 리고그고.*ngIfHTML의 원하지 않는 행을 방지합니다.

원래는 가지고 있었습니다.*ngIf그리고.*ngFor 편에<tr>태그, 하지만 작동하지 않습니다.이 되었습니다.<div>를해위를 .*ngFor하고 배치된 프앤스이플레루*ngIf에 시대에<tr>태그, 예상대로 작동합니다.

<table class="table lessons-list card card-strong ">
  <tbody>
  <div *ngFor="let lesson of lessons" >
   <tr *ngIf="lesson.isBeginner">
    <!-- next line doesn't work -->
    <!-- <tr *ngFor="let lesson of lessons" *ngIf="lesson.isBeginner"> -->
    <td class="lesson-title">{{lesson.description}}</td>
    <td class="duration">
      <i class="fa fa-clock-o"></i>
      <span>{{lesson.duration}}</span>
    </td>
   </tr>
  </div>
  </tbody>

</table>

Angular2 베타 8로 업데이트됨

부터 이제2 부타2 터할8 용사수8 있니다습각을 할 수 .*ngIf그리고.*ngFor동일한 구성요소에 대해 여기를 참조하십시오.

대체:

때때로 우리는 HTML 태그를 다른 태그 안에서 사용할 수 없습니다.tr,th(table) 또는 에서li(ul에서 몇 해야 HTML5 할 수 있습니다. ) 다 HTML 태 그 른 작 을 수 HTML5 태 수 야 다 해 있 니 사 HTML5 할 습 용 를 그 기 행<template>이런 식으로

ng템플릿 사용:

<template ngFor #abc [ngForOf]="someArray">
    code here....
</template>

ng템플릿을 사용하는 경우:

<template [ngIf]="show">
    code here....
</template>    

각도 2의 구조 지시에 대한 자세한 내용은 여기를 참조하십시오.

<div *ngFor="let thing of show ? stuff : []">
  {{log(thing)}}
  <span>{{thing.name}}</span>
</div>

다른 해결책은 표시하지 않으려는 경우 for 루프에 빈 배열을 넣는 것입니다.

<div *ngFor="let thing of show ? stuff : []">

여기서 "stuff"는 "thing"의 배열이며 내용을 표시하거나 표시하지 않을 부울의 "show"입니다.

<!-- Since angular2 stable release multiple directives are not supported on a single element(from the docs) still you can use it like below -->


<ul class="list-group">
                <template ngFor let-item [ngForOf]="stuff" [ngForTrackBy]="trackBy_stuff">
                    <li *ngIf="item.name" class="list-group-item">{{item.name}}</li>
                </template>
   </ul>

동일한 요소에 다중 구조 지시문을 사용할 수 없습니다.를 소를줄 바꿈요로 .ng-template 하나의 합니다.

배열 길이를 확인하여 다른 방법으로 이 작업을 수행할 수 있습니다.

<div *ngIf="stuff.length>0">
  <div *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </div>
</div>

그 중 하나가 *ngIf인 경우 두 개의 구조적 지침이 함께 작동할 수 있습니까?

아니요, 동일한 요소에 여러 구조적 지시어를 사용할 수 없습니다. 지시어 중 하나가 *ngIf이면 다른 지시어가 실패합니다.

이 지시 오류를 방지하려면 루프에 *ngSwitch 또는 ng-container 태그를 사용하고 내부에서는 ngIf를 사용하여 작업 코드를 가질 수 있습니다.

아래와 같이

    <ng-container *ngFor="let e of emp;">
        <tr *ngIf="e.name == txtname.value">
            <td>{{ e.name }}</td>
        </tr>
    </ng-container>

언급URL : https://stackoverflow.com/questions/34657821/ngif-and-ngfor-on-same-element-causing-error

반응형