Angular2变化检测无限循环

时间:2018-05-23 15:32:38

标签: angular angular2-changedetection

我们有一个带有输入属性的简单组件:

<app-example [exampleInput$]="exampleInputData$"></app-example>

在我们使用app-example的组件上,我们有:

get exampleInputData$(): any {
    var subject = new Subject<string>();
    console.log("Log1");

    this.exampleService.getAllData(this.id).subscribe(data => {
      console.log("Log2");
      subject.next(data);
    });

    return subject.asObservable();
  }

exampleService是一个简单的可观察对象:

public getAllData(id): Observable<ExampleObject[]> {
    return this.http.get(`${this.baseUrl}data/${id}`).map((response: Response) => {
      var data = <ExampleObject[]>response.json();
      return data;
    }).catch(this.handleError);
  }

当我们运行它时,它进入一个无限循环,如果我们改变changeDetection以推动它停止或者如果我们删除对getAllData的调用。有没有人知道为什么会导致无限循环?

以下是app-example组件和Html模板:

export class ExampleComponent implements OnDestroy {      
  private subscription: ISubscription;
  private parsedResponse : any;

  @Input() exampleInput$;

  getData(): void
  {    
    this.subscription = this.exampleInput$.subscribe((data) => {this.parsedResponse = data;},
      () => {
        // Here we download the data as CSV
      });
  }

  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }

模板:

<button class="btn btn-primary" (click)="getData()">
  Download As CSV
</button>

2 个答案:

答案 0 :(得分:1)

您正在绑定HTML中的方法。因此,在每次更改检测时,都会调用该方法。您需要将observable设置为属性,并将exampleInputData $()中的内容设置为ngOnInit

export AppComponent {

    subject = new Subject<string>();
    observable$ = subject.asObservable();
    id: number;

    ngOnInit() {
        // I expected you know how to get the id value
        this.exampleService.getAllData(this.id).subscribe(data => {
            this.subject.next(data);
        });
    }
}

和HTML

<app-example [exampleInput$]="observable$"></app-example>

答案 1 :(得分:0)

我不知道你的代码是如何进行的,但我认为你可能在每个渲染中调用exampleInputData $,你应该这样做:

Class Component implements OnInit {
    constructor(exampleInputDataService: ExampleInputDataService) {
    }

    ngOnInit(): void {
        this.data = this.exampleInputDataService.getData();
    }
}