简体   繁体   English

如何在子组件Angular中获取数组?

[英]How to get array in child component Angular?

I am passing array to child component but it return empty array with zero length, but in parent it works fine.我将数组传递给子组件,但它返回长度为零的空数组,但在父组件中它工作正常。

Check below检查下面在此处输入图片说明

Here is my code这是我的代码

HTML HTML

<app-schema-form [schema]="product_fields"></app-schema-form>

TS TS

export class SingleProductComponent implements OnInit {

  product_id: any;
  product_fields = [];

  constructor(...) { }

  ngOnInit() {
    this.product_id = ...;
    this.getProductFields();
  }

  getProductFields() {
    this.api.get('productfields', this.product_id).subscribe(res => {
      if (res[0]) {
        JSON.parse(res[0].product_fields).forEach(element => {
          this.product_fields.push(element);
        });
      }
      console.log(this.product_fields);
    })
  }
}

export class SchemaFormComponent implements OnInit {

  @Input() schema: string[];

  constructor() { }

  ngOnInit() {
    console.log(this.schema);
  }
}

You're logging the child values in the ngOnInit of the child.您正在子代的ngOnInit中记录子代值。 The parent will pass the value after your service has returned its value.在您的服务返回其值后,父级将传递该值。 Your service will certainly return the value after the child's ngOnInit has been called.您的服务肯定会在调用孩子的ngOnInit后返回该值。

To ensure you run code after the child value has been received, use ngOnChanges() .为确保您在收到子值后运行代码,请使用ngOnChanges()

The docs for ngOnChanges states that it is: ngOnChanges的文档说明它是:

A callback method that is invoked immediately after the default change detector has checked data-bound properties if at least one has changed, and before the view and content children are checked.如果至少有一个更改,则在默认更改检测器检查数据绑定属性后立即调用的回调方法,并且在检查视图和内容子项之前。

export class SchemaFormComponent implements OnChanges {

  @Input() schema: string[];

  constructor() { }

  ngOnChanges(changes: SimpleChanges) {
    if (changes.schema) {
      console.log(this.schema);
    }
  }
}

Another issue you are having is that you are initialising your product_fields array as empty.您遇到的另一个问题是您将product_fields数组初始化为空。 This means that when you push new values to your array, ngOnChanges() doesn't get run as it is still the same object .这意味着当您将新值推送到数组时, ngOnChanges()不会运行,因为它仍然是同一个 object Instead, leave your array as undefined and only set it once you have the data.相反,将您的数组保留为未定义,只有在您拥有数据后才设置它。 This will trigger ngOnChanges in the child once it is set.一旦设置,这将在子ngOnChanges中触发ngOnChanges

export class SingleProductComponent implements OnInit {

  product_id: any;
  product_fields: []; // <--- declare undefined array

  constructor(...) { }

  ngOnInit() {
    this.product_id = ...;
    this.getProductFields();
  }

  getProductFields() {
    this.api.get('productfields', this.product_id).subscribe(res => {
      if (res[0]) {
        // assign array here
        this.product_fields = JSON.parse(res[0].product_fields); 
      }
      console.log(this.product_fields);
    })
  }
}

Parent家长

export class SingleProductComponent implements OnInit {

  product_id: any;
  product_fields: any[];

  constructor(...) { }

  async ngOnInit() {
    this.product_id = ...;
    await this.getProductFields();
  }

   async getProductFields() {
      const response = await this.api.get('productfields', this.product_id).toPromise();
      if (response[0]) {
         this.product_fields = JSON.parse(response[0].product_fields);
      }
      console.log(this.product_fields);
  }

HTML HTML

<app-schema-form [schema]="product_fields"></app-schema-form>

Child孩子

export class SchemaFormComponent implements OnInit, OnChanges {

  private _schema: string[];
  public get schema(): string[] {
    return this._schema;
  }

  @Input()
  public set schema(value: string[]) {
    this._schema = value;
  }

  constructor() { }

  ngOnChanges(changes: SimpleChanges) {
     if (changes.schema) {
        console.log(this.schema);
     }
  }
}

In order to trigger angular's life cycle you need to create a change of reference.为了触发 angular 的生命周期,您需要创建引用的更改。 When you use当你使用

JSON.parse(res[0].product_fields).forEach(element => {
    this.product_fields.push(element);
});

you push elements to an existing array.您将元素推送到现有数组。 In order to change the reference of the array all you need to do is为了改变数组的引用,你需要做的就是

this.product_fields = [...res[0].product_fields]

Now, since you get the products in an async way, you cannot assume that the data is there on init.现在,由于您以异步方式获取产品,因此您不能假设数据在 init 上。 I'd do the following:我会做以下事情:

export class SchemaFormComponent {
    private _schema: string[];
    @Input() set schema(_schema: string[]) {
        console.log('_schema: ', _schema);
        this._schema = _schema;
    }

    get schema(): string[] {
        return this._schema;
    }

    constructor() { }
}

Hope this helps!希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM