OnChanges 不会检测到更改
OnChanges won't detect the changes
我正在创建一个简单的应用程序。然后我将一个数组传递给子组件。当我从数组中删除一个项目时,ngOnChanges
不会检测到更改,除非我刷新页面。
我只能在第一个页面加载时记录更改一次,但在数组更改时不能。
提前感谢您的宝贵时间。
父组件:
<div class="wrapper">
<div class="cart-container">
<h1>In Cart</h1>
<mat-card class="list-item" *ngFor="let x of shoppingCart">
<div class="list-title">{{ x.title }}</div>
<button color="warn" mat-icon-button (click)="deleteFromCart(x)">
<mat-icon class="material-icons">clear</mat-icon>
</button>
</mat-card>
<app-calculator [shoppingCart]="shoppingCart"></app-calculator>
</div>
<hr />
<app-favourites></app-favourites>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { ProductModel } from 'src/app/models/product/product-model';
import { CartService } from 'src/app/services/cart.service';
@Component({
selector: 'app-shopping-cart',
templateUrl: './shopping-cart.component.html',
styleUrls: ['./shopping-cart.component.scss']
})
export class ShoppingCartComponent implements OnInit {
public shoppingCart: ProductModel[] = [];
constructor(
private cartService: CartService
) {}
ngOnInit(): void {
this.getItems();
}
getItems(): void {
this.shoppingCart = this.cartService.getItems();
}
deleteFromCart(item: ProductModel): void {
this.shoppingCart = this.cartService.deleteItemFromCart(item);
}
}
子组件:
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { ProductModel } from 'src/app/models/product/product-model';
@Component({
selector: 'app-calculator',
templateUrl: './calculator.component.html',
styleUrls: ['./calculator.component.scss']
})
export class CalculatorComponent implements OnChanges {
@Input() shoppingCart: ProductModel[] = [];
public total: number = 0;
constructor() {}
ngOnChanges(changes: SimpleChanges): void {
console.log(changes)
}
}
我想问题出在您的更改检测上。我不确定您的服务到底是什么样子,以及它是 returns 可观察的还是数组,所以检查问题出在哪里的最简单方法是:
在您的 deleteFromCart()
中记录 this.shoppingCart
。如果它注销了正确的结果(因此该项目被删除) - 这意味着问题出在变化检测上。也许您没有再次分配数组,您只是在修改它,所以 angular 不会检查更改。这意味着您有两种选择来解决问题。更好的方法:
deleteFromCart(item: ProductModel): void {
this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
}
这会将一个全新的数组分配给 this.shoppingCart
并会触发 angular 检查更改。 “更糟糕”的方法是在构造函数中添加 private changeDetectorRef: ChangeDetectorRef
,然后:
deleteFromCart(item: ProductModel): void {
this.shoppingCart = this.cartService.deleteItemFromCart(item);
this.changeDetectorRef.markForChanges()
}
这将告诉 angular 他必须检查是否有任何更改 - 但这不是一个好方法(最好避免 changeDetectorRef
)
如果您的日志显示结果仍然相同 - 那么这意味着您的服务做错了什么,然后您应该检查那里发生了什么 - 您可以粘贴代码在这里,我们可以提供帮助。
试试这个:
deleteFromCart(item: ProductModel): void {
this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
}
但更正确的做法是 cartService.deleteItemFromCart returns 未删除项目的项目数组的副本,而不是返回删除项目的同一数组。
你是对的,添加或删除项目不会引发 onChanges 事件,因为数组对象的引用没有改变。如果你想强制 onChanges 那么你每次修改数组时都必须创建一个新的数组对象。像这样
deleteFromCart(item: ProductModel): void {
this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
}
否则,如果您只想检查是否引发了数组更改事件,您还有很多其他方法,例如,您可以将数组放在一个服务中,它可以从父组件和子组件访问,或者您可以创建一个主题并在子组件中订阅它。
我正在创建一个简单的应用程序。然后我将一个数组传递给子组件。当我从数组中删除一个项目时,ngOnChanges
不会检测到更改,除非我刷新页面。
我只能在第一个页面加载时记录更改一次,但在数组更改时不能。
提前感谢您的宝贵时间。
父组件:
<div class="wrapper">
<div class="cart-container">
<h1>In Cart</h1>
<mat-card class="list-item" *ngFor="let x of shoppingCart">
<div class="list-title">{{ x.title }}</div>
<button color="warn" mat-icon-button (click)="deleteFromCart(x)">
<mat-icon class="material-icons">clear</mat-icon>
</button>
</mat-card>
<app-calculator [shoppingCart]="shoppingCart"></app-calculator>
</div>
<hr />
<app-favourites></app-favourites>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { ProductModel } from 'src/app/models/product/product-model';
import { CartService } from 'src/app/services/cart.service';
@Component({
selector: 'app-shopping-cart',
templateUrl: './shopping-cart.component.html',
styleUrls: ['./shopping-cart.component.scss']
})
export class ShoppingCartComponent implements OnInit {
public shoppingCart: ProductModel[] = [];
constructor(
private cartService: CartService
) {}
ngOnInit(): void {
this.getItems();
}
getItems(): void {
this.shoppingCart = this.cartService.getItems();
}
deleteFromCart(item: ProductModel): void {
this.shoppingCart = this.cartService.deleteItemFromCart(item);
}
}
子组件:
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { ProductModel } from 'src/app/models/product/product-model';
@Component({
selector: 'app-calculator',
templateUrl: './calculator.component.html',
styleUrls: ['./calculator.component.scss']
})
export class CalculatorComponent implements OnChanges {
@Input() shoppingCart: ProductModel[] = [];
public total: number = 0;
constructor() {}
ngOnChanges(changes: SimpleChanges): void {
console.log(changes)
}
}
我想问题出在您的更改检测上。我不确定您的服务到底是什么样子,以及它是 returns 可观察的还是数组,所以检查问题出在哪里的最简单方法是:
在您的
deleteFromCart()
中记录this.shoppingCart
。如果它注销了正确的结果(因此该项目被删除) - 这意味着问题出在变化检测上。也许您没有再次分配数组,您只是在修改它,所以 angular 不会检查更改。这意味着您有两种选择来解决问题。更好的方法:deleteFromCart(item: ProductModel): void { this.shoppingCart = [...this.cartService.deleteItemFromCart(item)]; }
这会将一个全新的数组分配给
this.shoppingCart
并会触发 angular 检查更改。 “更糟糕”的方法是在构造函数中添加private changeDetectorRef: ChangeDetectorRef
,然后:deleteFromCart(item: ProductModel): void { this.shoppingCart = this.cartService.deleteItemFromCart(item); this.changeDetectorRef.markForChanges() }
这将告诉 angular 他必须检查是否有任何更改 - 但这不是一个好方法(最好避免
changeDetectorRef
)如果您的日志显示结果仍然相同 - 那么这意味着您的服务做错了什么,然后您应该检查那里发生了什么 - 您可以粘贴代码在这里,我们可以提供帮助。
试试这个:
deleteFromCart(item: ProductModel): void {
this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
}
但更正确的做法是 cartService.deleteItemFromCart returns 未删除项目的项目数组的副本,而不是返回删除项目的同一数组。
你是对的,添加或删除项目不会引发 onChanges 事件,因为数组对象的引用没有改变。如果你想强制 onChanges 那么你每次修改数组时都必须创建一个新的数组对象。像这样
deleteFromCart(item: ProductModel): void {
this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
}
否则,如果您只想检查是否引发了数组更改事件,您还有很多其他方法,例如,您可以将数组放在一个服务中,它可以从父组件和子组件访问,或者您可以创建一个主题并在子组件中订阅它。