看起来这个问题很受欢迎,在我的阵列中推送新的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;
}
我试图在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)
);
}
答案 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
请注意,服务和组件位于同一个文件中,但仅适用于示例