typescript - Array skapad med array.push() har element men kunde inte använda Angular


Jag har 2 Array<object>. En av dem har initiala element och den andra har sina element tillagda med array.push() i ngOnInit. I slutändan har båda elementen i utdata men HTML renderar inte de element som lades till med .push

//the result of array that made by array.push
> [] 
 > 0: {id: '1', title: 'title 1'}
 > 1: {id: '2', title: 'title 2'}
 > 2: {id: '3', title: 'title 3'}
   length: 3
 > __proto__: Array(0)


//initialize array
> (3) [{…}, {…}, {…}] 
 > 0: {id: '1', title: 'title 1'}
 > 1: {id: '2', title: 'title 2'}
 > 2: {id: '3', title: 'title 3'}
   length: 3
 > __proto__: Array(0)

koden

newObj;
error;

myObjects: Array<object> = [];

itsObjects: Array<object> = [
  {
    id: '1',
    title: 'title 1'
  },
  {
    id: '2',
    title: 'title 2'
  },
  {
    id: '3',
    title: 'title 3'
  }
];

ngOnInit() {
  this.subscription = this.mys.myService().subscribe(
    res => {
      this.newObj = res,
      this.myObjects.push(
          {
            id: element.id,
            title: element.title
          }
        )
    },
    error => this.error = error,
  )
}

Löst

Huvudmeddelandet var this.myObjects=this.tmpObj efter forEach som samlar alla element för att passera till utanför ngOnInit-omfånget, jag redigerade min kod till:

servicOutput; //get data
tmpObj: Array<object> = []; //manage data as temp;
myObjects: Array<object> = []; //for collect all elements to html
error;

ngOnInit() {
  this.subscription = this.mys.myService().subscribe(
    res => {
      this.servicOutput = res,
      this.servicOutput.forEach(element => {
        this.pushFunc(element);
        }
      ),
      this.myObjects = this.tmpObj; //here collect all elements as an object and pass out of ngOnInit scope
    },
    error => this.error = error,
  )
}

pushFunc(element) {
  this.tmpObj.push(
    {
      id:    element.id,
      title: element.title
    }
  )
}

Svar #1

Angulars mekanism för ändringsdetektion hanterar inte innehållsförändringar i en array. Du kan antingen ändra referensen till arrayen som xdecdec föreslog tidigare i kommentarerna, eller så kan du implementera din egen ngDoChange så att du kan implementera ditt eget sätt att upptäcka förändringen av arrayens innehåll.

Kolla detta svar för ytterligare förklaring om hur man implementerar ngDoChange: https://stackoverflow.com/a/42962723/11420760

Svar #2

Angular upptäcker inte förändringar inom en array. Den upptäcker bara när referensen till arrayen själv förändras. För att få HTML att renderas om behöver du använda en av följande metoder som kommer att meddela Angular att något har förändrats.

Metod 1 - Använd rest-/spread-operatorn istället för push för att ändra arrayen

Beröm till Rushi Patel för denna metod.

this.myObjects = [...this.myObjects, this.newObj[0]];

Metod 2 - Använd rest-/spridningsoperatorn för att ändra arrayreferensen efter en push

this.myObjects.push(this.newObj[0]);
this.myObjects = [...this.myObjects];

Metod 3 - Använd JSON.stringify/parse för att ändra arrayreferens efter en push

this.myObjects.push(this.newObj[0]);
this.myObjects = JSON.parse(JSON.stringify(this.myObjects));

Metod 4 - Använd detectChanges() för att meddela Angular att något har ändrats

Detta föreslås också i https://stackoverflow.com/a/57689299/470014

constructor(private changeDetectorRef: ChangeDetectorRef) { }

public testMethod() {
    this.myObjects.push(this.newObj[0]);
    this.changeDetectorRef.detectChanges();}

Relaterade artiklar