Angular 6:从父组件接收数据后,在ngAfterContentChecked内部连续执行http请求

时间:2018-10-10 03:37:14

标签: javascript angular reactjs typescript

我是Angular的新手,来自React.js

我遇到一个问题,即从父组件接收数据后,Angular会在HTTP内永远发出ngAfterContentChecked请求

我无法在ngAfterContentInit内发出请求,因为我需要等待父母完成请求

我只希望它在从父级获取数据后立即调用一次

通常在React.js中,我在componentWillReceiveProps内进行请求

在Angular中,我这样做。

父组件:

//codes...
groupId = '';
//codes...

ngOnInit() {
  const id = '23esaddq3sdasd';
  this.dataService.getUser(id).subscribe(data => {
    //codes...
    this.groupId = data.groupId;
    //codes...
  });
}

子组件:

data = [];
@Input() groupId;
fetch;

ngAfterContentChecked() {
  if (this.groupId) {
    const res = this.dataService.getGroupMembers(this.groupId).subscribe(data => 
      this.data = data;
      this.fetch = 'done';
    });
    if (this.fetch === 'done') {
      res.unsubscribe();
    }
  }
}

我尝试unsubscribe,但仍继续执行代码。

任何人,请帮助我

4 个答案:

答案 0 :(得分:2)

您可以使用ngOnChanges()代替ngAfterContentChecked,当父级使用@input()将数据传递给子组件时,它将触发。

如果您具有投影内容“ ng-content”并访问父组件更改检测上的任何DOM,则会使用

ngAfterContentChecked生命周期。

答案 1 :(得分:2)

您要使用ngOnChanges,因为每次@Input值更改时都会触发。

ngOnChanges的完整签名为:

ngOnChanges(changes: SimpleChanges): void

因此,请检查changes对象以查看它是否包含对@Input的更改,并且该值符合预期,然后发出如下HTTP请求:

ngOnChanges(changes: SimpleChanges) {
  if (changes.groupId != null && fetch !== 'done') {
    const res = this.dataService.getGroupMembers(this.groupId).subscribe(data => 
      this.data = data;
      this.fetch = 'done';
    });
  }
}

不需要取消订阅,因为HTTP请求的订阅将自动完成。要证明这一点,请执行以下操作:

    const res = this.dataService.getGroupMembers(this.groupId).subscribe(data => 
      this.data = data;
      this.fetch = 'done';
    },
    err => {
      console.log('I errored');
    },
    () => {
      console.log('I completed and won't fire again');
    });

PS ngAfterContentChecked疯狂发射的原因是它执行得非常规律。

答案 2 :(得分:1)

对我来说,我会这样:

  1. 父触发器http,您需要设置一个isLoading = true之类的标志
  2. 在.html中,对子组件使用*ngIf="!isLoading "
  3. 父级收到请求后,设置isLoading = false
  4. 这将使子组件呈现,并且您可以在子组件内部使用ngOnInit钩子来接收来自父组件的数据
  5. 子组件在ngOnInit中收到父组件的输入后,您可以触发http

答案 3 :(得分:0)

您可以使用setter和getter代替ngOnChanges,它们仅在父级使用@input()将数据传递给子级组件时触发。

ngOnChanges始终在父组件或子组件中的任何内容发生更改时运行。

  private _name;
  get name() { return this._name };
  @Input() set name(val: string) {
      if (val) {
          this._name = val;
          this.getGreetings(this.name)
      }
  };
  greetings = '';
  processing = false;
  constructor(){}

  getGreetings(name){
      this.processing = true;
      setTimeout(()=>{
          this.greetings = 'Hi.. '+name+', How are you';
          this.processing = false;
      },2000)
  }

有效的演示链接:-Ckick Here