数组推送的Angular 4更新视图

时间:2017-12-31 10:10:07

标签: angular

看起来这个问题很受欢迎,在我的阵列中推送新的element之后,我多次尝试更新我的视图,但没有任何反应。

我将解释我的功能和我正在尝试做的事情,我会告诉你我的尝试。

我的第一个组件是car.component.ts,我曾用carsService显示调用API的汽车列表。

carsList() {
        this._carsListService.carsService(this.user)
            .subscribe(
                response => {
                        this.result = response;
                        if (this.result.code != 200) {
                             //error response message
                        }
                        else if (this.result.code == 200) {
                            this.data = [] = this.data;
                            this.result.cars.forEach(element => {
                                this.data.push(element);
                            });
                        }
                },
                error => console.log(error)
            );
    }

第二个组件是insert.component.ts我可以添加一个带有详细信息的新车,而carsList应该检测到我正在寻找的变化。

insertNew() {
        this._insertService.insertNewService(this.user)
            .toPromise()
            .then(
                response => {
                    this.result = response;
                    if (this.result.status != 200) {
                       //error message
                    } else {
                       // new element inserted and now it is in cars list API
                    }
                },
                error => console.log(error)
            );

    }

现在在car.component.html

 <div *ngFor="let element of data" id="{{element.car_id}}">
    <mat-card>
        <mat-card-content>
          //some details about cars
        </mat-card-content>
    </mat-card>
 </div>

现在一切正常,但是当insertNew()调用并插入任何新元素时,carsList视图中没有任何变化。

1 - 我尝试使用ngZone

运行我的功能
carsList() {
            this._carsListService.carsService(this.user)
                .subscribe(
                    response => {
                    this.zone.run(() => { // <==
                            this.result = response;
                            if (this.result.code != 200) {
                                 //error response message
                            }
                            else if (this.result.code == 200) {
                                this.data = [] = this.data;
                                this.result.cars.forEach(element => {
                                    this.data.push(element);
                                });
                            }
                             console.log("using ngzone"); //this console appeared just one time even when I insert anything new
                             });
                    },
                    error => console.log(error)
                );
        }

2 - 我尝试使用Angular中包含的DoCheck算法,它看起来像 用<div *ngFor="let element of data" id="{{element.car_id}}">替换此行<div *ngFor="#element of data" id="{{element.car_id}}">,但Angular说(意外的令牌#)。

#EDIT

我的服务

carsService(value: Object) {
        return this._appService.LoadAPI(value, this.carsAPI);
    }

LoadAPI

public loadScript(src) {
        let script = document.createElement('script');
        script.type = 'text/javascript';
        document.getElementsByTagName('body')[0].appendChild(script);
        script.src = src;
    }

编辑2

我试图在carList()

中调用insertNew()函数
constructor( public cars_list: CarComponent)

insertNew() {
            this._insertService.insertNewService(this.user)
                .toPromise()
                .then(
                    response => {
                        this.result = response;
                        if (this.result.status != 200) {
                           //error message
                        } else {
                    this.cars_list.carsList();
                           // new element inserted and now it is in cars list API
                        }
                    },
                    error => console.log(error)
                );

        }

1 个答案:

答案 0 :(得分:2)

这样做的一种方法是创建一个Observable,只要它发生变化,就会发出您感兴趣的数据。它将在服务中进行管理,任何必要的组件都可以订阅Observable

当您再调用insertNew时,如果该API调用返回已添加的项,您只需将其添加到现有数据中,然后通知observable,而无需再进行其他API调用。

通过让您的组件订阅Observable,他们无需知道何时获取更新数据,只需将其推送给他们即可。这也意味着无论哪个组件调用该服务,所有组件都将通过可观察的

接收更新的数据

这是一个表明我的意思的例子:

@Injectable()
export class CarListService {

  const root = 'https://jsonplaceholder.typicode.com';

  // This is your data.
  private data = [];
  // This subject will be used to update the observable
  private _carList = new Subject();

  // This observable is public so that your components can subscribe
  carList$ = this._carList.asObservable();

  constructor(private http: HttpClient) {
    // The notify function emits the data variable out of the observable
    // In it's initial state, it is simply an empty array
    this.notify();
  }

  loadList(): void {
    // Here, we can get our data from the API. Note that this function
    // does not return anything
    this.http.get(this.root + '/users').subscribe((res) => {
      // We update data with what comes back, and call notify again 
      // so that the observable emits the latest data
      this.data = res;
      this.notify();
    })
  }

  insertNew():void {
    // Here we are updating the API
    this.http.post(this.root + "/users", {
      name: "This is my new one"
    }).subscribe((res) => {
      // The API returns our newly created item, so append it to data, and 
      // call notify again to update the observable
      this.data.push(res);
      this.notify();
    })
  }

  private notify() {
    // Call next on the subject with the latest data
    this._carList.next(this.data);
  }
}

如果你想看到这个,我已经创建了一个用来表明我的意思 https://plnkr.co/edit/lLfFcqYqawKcyi3tLtQe?p=preview

请注意,服务和组件位于同一个文件中,但仅适用于示例