2016-07-19 2 views
4

을 사용하여 생성 된 목록 주위에 ngIf 컨테이너를 래핑하면 Angular2에서 예상치 못한 동작이 발생합니다. ngIf 컨테이너가 표시된 후 처음으로 삽입 될 때 뷰가 관찰 가능 배열의 항목을 렌더링하지 않는 것처럼 보입니다.ng 컨테이너가 비동기식으로 깨짐

이 예기치 않은 동작을 나타내는 plunker demo을 참조하십시오. 나는 첫 번째 예제가 바나나을 동시에 나타낼 것이라고 기대하고 있습니다. 로드 됨이 나타납니다.

나는 바보 같은 짓을하고 있는가? 아니면 렌더링 버그인가?


Plunker demo

app.service.ts

export class AppService { 
    private _things = new Subject<Array<any>>(); 
    public things = this._things.asObservable(); 

    constructor() { 
    var that = this; 

    // simulate ajax request 
    setTimeout(function() { 
     that._things.next([ 
      {'id': 1, 'text': 'banana'} 
     ]); 
    }, 3000); 

    setTimeout(function() { 
     that._things.next([ 
     {'id': 1, 'text': 'banana'}, 
     {'id': 2, 'text': 'orange'} 
     ]); 
    }, 6000); 

    setTimeout(function() { 
     that._things.next([ 
     {'id': 1, 'text': 'banana'}, 
     {'id': 2, 'text': 'orange'}, 
     {'id': 3, 'text': 'apple'} 
     ]); 
    }, 9000); 
    } 
} 

app.ts

@Component({ 
    selector: 'my-app', 
    template: ` 
    <h4>Does have *ngIf</h4> 
    <div *ngIf="hasThings"> 
     Loaded 
     <ul> 
     <li *ngFor="let thing of things | async"> 
      {{thing.id}}: {{thing.text}} 
     </li> 
     </ul> 
    </div> 

    <h4>Doesn't have *ngIf</h4> 
    <div> 
     Loaded 
     <ul> 
     <li *ngFor="let thing of things | async"> 
      {{thing.id}}: {{thing.text}} 
     </li> 
     </ul> 
    </div> 
    `, 
    directives: [NgClass, NgStyle, CORE_DIRECTIVES, FORM_DIRECTIVES] 
}) 
export class App implements OnInit { 
    public hasThings = false; 

    private _things = new Subject<Array<any>>(); 
    public things = this._things.asObservable(); 

    constructor(private _appService: AppService) { 
    } 

    ngOnInit() { 
    this._appService.things 
     .subscribe(things => { 
     this.hasThings = things.length > 0; 
     this._things.next(things); 
     }); 
    } 
} 
+0

귀하의 쿵하는 소리가 나를 위해 작동하는 것 같다 ... –

답변

5

구성 요소에 Subject, 템플릿에 async 파이프를 사용하고있는 이유는 무엇입니까? 구성 요소의 Subject 개체를 BehaviorSubject으로 변경하면 예상되는 결과가 나타납니다. Subject하지 않는 경우 SubjectBehaviorSubject의 주요 차이점의

private _things = new BehaviorSubject<Array<any>>(); 

하나는 BehaviorSubject 돌아갑니다 당신이에 가입 할 때 잘 유지의 마지막 값입니다. 코드에서 처음으로 ngIf 조건이 충족되면 DOM이 시작되고 첫 번째 목록에서는 subscribe이 호출됩니다. 그 때 Subject은 아무 것도 방출하지 않으며 목록을 업데이트하기 위해 다음 이벤트까지 기다려야합니다.

근무 plnkr : https://plnkr.co/edit/Obso0Odl3PoPw699AQ5W?p=preview

+1

당신은 그것을 시도 했습니까? 왜냐하면 그것은 작동하지 않는 것 같습니다. – sirrocco

+2

그래, 여기 내 plnkr (자신의 유일한 수입 라인 및 선언 라인에서 포크) : https://plnkr.co/edit/Obso0Odl3PoPw699AQ5W?p=preview –

+0

아, 고마워! 처음에는 구성 요소 대신 서비스에 대해 'BehaviorSubject'를 사용 했으므로 처음에는 작동하지 않는다고 생각했습니다. 아마 둘 다 사용해야한다고 생각합니다. 모호성을 제거하기 위해 답을 업데이트 할 것을 제안 할 수 있습니까? – ajbeaven

관련 문제