TypeError:无法在Array.push(<anonymous>)处添加属性1,对象不可扩展

时间:2018-09-25 06:44:17

标签: angular typescript rxjs

我正在尝试向数组中添加一些数据,但是却出现了不可扩展的错误。

组件代码:

this._store.select(p => p.collection.workspaceCollectionPages).subscribe((data: CollectionPageDbModel[]) =>{
      if(data){
      return data.map((collectionPageDbModel)=> {

      this.collectionPages.push(collectionPageDbModel) //Getting error on this line while pushing

    });}

enter image description here

我的数据变量中有四个对象,我试图将其推入collectionPages,但在推入时却遇到了可扩展的错误。

enter image description here 我需要在其中添加更多数据的collectionPage数组

enter image description here 我需要推送的数据

CollectionPageDbModel:

export class CollectionPageDbModel implements IDbModel {
  public id?: number;
  public collection_version_id: number;
  public user_id?: string;
  public name: string;
  public position?: number = 0;
  public contents: string;
  public created_at?: string;
  public updated_at?: string;
  public server_id?: any;

}

有人可以帮我解决这个问题吗

4 个答案:

答案 0 :(得分:3)

Daniel提出的解决方案当然适用于这种情况。原因是每个JS对象都有的对象描述符。您可以通过调用Object.getOwnPropertyDescriptors(obj)来检出它们,因为(几乎)所有事物都是对象,所以它也适用于数组。

该问题中最可能使用的NGRX存储选择器通过使用Object.defineProperties(obj)来修改对象描述符。这样做是为了防止Reducer外部的Store中的数据发生任何变化(这也不改变状态,只是创建一个新数据)。

一般情况下,您必须克隆要突变的对象:


import { cloneDeep } from 'lodash'

// ...

constructor(private store: Store<any>) {}

someMethod() {
  let someDataFromTheStore = cloneDeep(this.store.select(selectSomeData))
  someDataFromTheStore.myArray.push('...')
}


Object.assigncloneDeep都不会将描述符传输到新副本。

Object.getOwnPropertyDescriptors

Object.defineProperties

答案 1 :(得分:1)

使用Object.assign方法复制对象,然后重试,

this.collectionPages = Object.assign([], this.collectionPages);
this.collectionPages.push(collectionPageDbModel);

答案 2 :(得分:0)

单线是:

this.collectionPages = this.collectionPages.slice().push(collectionPageDbModel);

答案 3 :(得分:0)

这个有用,

if(data){
   const result = data.map((collectionPageDbModel)=> {
      this.collectionPages.push(collectionPageDbModel) //Getting error on this line while pushing
   });
   
   return result
   // incase of async call this one will work fine
   // return Promise.all(result)
}