ngIf容器打破异步ngFor

ajb*_*ven 4 rxjs angular

当我ngIf在使用创建的列表周围包装容器时,我在Angular2中遇到了一些意外的行为ngFor.看起来好像视图在ngIf容器变得可见之后第一次插入时不会在可观察数组中呈现项目.

请参阅演示此意外行为的plunker演示.我期待第一个例子在Loaded出现的同时显示香蕉.

我做了一些愚蠢的事情还是这个渲染错误?


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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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);
      });
  }
}
Run Code Online (Sandbox Code Playgroud)

Har*_*inh 5

原因是您在模板Subject中的Component和asyncpipe中使用.如果Subject将Component中的对象更改为BehaviorSubject,则会得到预期的结果.

private _things = new BehaviorSubject<Array<any>>();
Run Code Online (Sandbox Code Playgroud)

Subject和之间的主要区别之一BehaviorSubjectBehaviorSubject返回它在订阅时保留的最后一个值,何时Subject不是.在您的代码中,当ngIf满足第一个条件时,将启动DOM并调用第一个列表subscribe.那时,Subject不会发出任何东西,你必须等到下一个事件才能更新列表.

工作plnkr:https://plnkr.co/edit/Obso0Odl3PoPw699AQ5W p = preview

  • 是的,这是我的plnkr(从他的,仅编辑的导入行和声明行分叉):https://plnkr.co/edit/Obso0Odl3PoPw699AQ5W?p = preview (2认同)