因多次零钱扣除而导致总价值错误如何防止?
Getting wrong total value because of multiple change deduction how to prevent?
我得到了错误的值,因为扣除了多次零钱。如何预防?
app.component.ts :
import { Component, OnInit } from "@angular/core";
interface PropsData {
productName: string;
value: number;
count: number;
details: (value1: number, value2: number) => number;
}
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
products: PropsData[];
allTotal: number = 0;
ngOnInit() {
this.products = [
{
productName: "sugar",
value: 20,
count: 1,
details: (value1, value2) => {
return this.grandTotal(value1, value2);
}
},
{
productName: "salt",
value: 40,
count: 1,
details: (value1, value2) => {
return this.grandTotal(value1, value2);
}
},
{
productName: "jackery",
value: 70,
count: 1,
details: (value1, value2) => {
return this.grandTotal(value1, value2);
}
}
];
}
updateCount(product: PropsData) {
product.count++;
}
updateAllTotal(itemTotal: number): void {
this.allTotal = this.allTotal + itemTotal;
}
grandTotal(value1, value2): number {
const total = value1 * value2;
this.updateAllTotal(total);
return total;
}
}
html:
<div>
<div *ngFor="let product of products">
<h1>{{product.productName}}</h1>
<p>{{product.count}}</p>
<p>Total: {{product.details(product.count, product.value)}}</p>
<p><button (click)="updateCount(product)">Add Product</button></p>
</div>
<h2>Grand Total: {{allTotal}}</h2>
</div>
作为一般规则,应使用绑定到方法 :在您的情况下,我将重构代码以避免绑定到 product.details()
。
第一个解决方案
一个简单的方法是在更新时声明一个事件发射器通知product.count
:product.details
可以变成一个简单的属性(而不是一个方法)并且在事件处理程序中更新。
interface PropsData {
productName: string;
value: number;
count: number;
details: number;
}
您的组件可能如下所示:
products: PropsData[];
allTotal: number = 0;
onProductUpdate = new EventEmitter<PropsData>();
ngOnInit() {
this.products = [
{
productName: "sugar",
value: 20,
count: 1,
details: 20 // Needs to be manually initialized, as it's not a function anymore
},
{
productName: "salt",
value: 40,
count: 1,
details: 40
},
{
productName: "jackery",
value: 70,
count: 1,
details: 70
}
];
this.updateAllTotal(); // Compute allTotal the first time
// On every product update compute product.details and allTotal
this.onProductUpdate.subscribe((product) => {
product.details = this.getProductDetails(product);
this.updateAllTotal();
});
}
updateCount(product: PropsData) {
product.count++;
this.onProductUpdate.next(product);
}
updateAllTotal(): void {
this.allTotal = 0;
this.products.forEach(
(item) => (this.allTotal = this.allTotal + item.details)
);
}
getProductDetails(product): number {
return product.count * product.value;
}
现在这可能是您的模板(不再有函数绑定):
<div>
<div *ngFor="let product of products">
<h1>{{product.productName}}</h1>
<p>{{product.count}}</p>
<p>Total: {{product.details}}</p>
<p><button (click)="updateCount(product)">Add Product</button></p>
</div>
<h2>Grand Total: {{allTotal}}</h2>
</div>
备选方案
根据您的实际用例的复杂程度,另一种方法是在产品本身中封装每次 value
或 count
更改时更新其详细信息的逻辑。为此,您需要将 PropsData
更改为 class:
class PropsData {
productName: string;
private _value: number;
private _count: number;
public get value() {
return this._value;
}
public set value(value) {
this._value = value;
this.details = this._value * this._count;
}
public get count() {
return this._count;
}
public set count(value) {
this._count = value;
this.details = this._value * this._count;
}
details: number;
constructor(name: string, value: number, count: number) {
this.productName = name;
this.count = count;
this.value = value;
}
}
如您所见,value
和 count
setter 也负责更新 details
。这简化了组件的逻辑:
products: PropsData[];
allTotal: number = 0;
ngOnInit() {
this.products = [
new PropsData("sugar", 20, 1),
new PropsData("salt", 40, 1),
new PropsData("jackery", 70, 1)
];
this.updateAllTotal();
}
updateCount(product: PropsData) {
product.count++;
this.updateAllTotal();
}
updateAllTotal(): void {
this.allTotal = 0;
this.products.forEach(
(item) => (this.allTotal = this.allTotal + item.details)
);
}
我得到了错误的值,因为扣除了多次零钱。如何预防?
app.component.ts :
import { Component, OnInit } from "@angular/core";
interface PropsData {
productName: string;
value: number;
count: number;
details: (value1: number, value2: number) => number;
}
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
products: PropsData[];
allTotal: number = 0;
ngOnInit() {
this.products = [
{
productName: "sugar",
value: 20,
count: 1,
details: (value1, value2) => {
return this.grandTotal(value1, value2);
}
},
{
productName: "salt",
value: 40,
count: 1,
details: (value1, value2) => {
return this.grandTotal(value1, value2);
}
},
{
productName: "jackery",
value: 70,
count: 1,
details: (value1, value2) => {
return this.grandTotal(value1, value2);
}
}
];
}
updateCount(product: PropsData) {
product.count++;
}
updateAllTotal(itemTotal: number): void {
this.allTotal = this.allTotal + itemTotal;
}
grandTotal(value1, value2): number {
const total = value1 * value2;
this.updateAllTotal(total);
return total;
}
}
html:
<div>
<div *ngFor="let product of products">
<h1>{{product.productName}}</h1>
<p>{{product.count}}</p>
<p>Total: {{product.details(product.count, product.value)}}</p>
<p><button (click)="updateCount(product)">Add Product</button></p>
</div>
<h2>Grand Total: {{allTotal}}</h2>
</div>
作为一般规则,应使用绑定到方法 product.details()
。
第一个解决方案
一个简单的方法是在更新时声明一个事件发射器通知product.count
:product.details
可以变成一个简单的属性(而不是一个方法)并且在事件处理程序中更新。
interface PropsData {
productName: string;
value: number;
count: number;
details: number;
}
您的组件可能如下所示:
products: PropsData[];
allTotal: number = 0;
onProductUpdate = new EventEmitter<PropsData>();
ngOnInit() {
this.products = [
{
productName: "sugar",
value: 20,
count: 1,
details: 20 // Needs to be manually initialized, as it's not a function anymore
},
{
productName: "salt",
value: 40,
count: 1,
details: 40
},
{
productName: "jackery",
value: 70,
count: 1,
details: 70
}
];
this.updateAllTotal(); // Compute allTotal the first time
// On every product update compute product.details and allTotal
this.onProductUpdate.subscribe((product) => {
product.details = this.getProductDetails(product);
this.updateAllTotal();
});
}
updateCount(product: PropsData) {
product.count++;
this.onProductUpdate.next(product);
}
updateAllTotal(): void {
this.allTotal = 0;
this.products.forEach(
(item) => (this.allTotal = this.allTotal + item.details)
);
}
getProductDetails(product): number {
return product.count * product.value;
}
现在这可能是您的模板(不再有函数绑定):
<div>
<div *ngFor="let product of products">
<h1>{{product.productName}}</h1>
<p>{{product.count}}</p>
<p>Total: {{product.details}}</p>
<p><button (click)="updateCount(product)">Add Product</button></p>
</div>
<h2>Grand Total: {{allTotal}}</h2>
</div>
备选方案
根据您的实际用例的复杂程度,另一种方法是在产品本身中封装每次 value
或 count
更改时更新其详细信息的逻辑。为此,您需要将 PropsData
更改为 class:
class PropsData {
productName: string;
private _value: number;
private _count: number;
public get value() {
return this._value;
}
public set value(value) {
this._value = value;
this.details = this._value * this._count;
}
public get count() {
return this._count;
}
public set count(value) {
this._count = value;
this.details = this._value * this._count;
}
details: number;
constructor(name: string, value: number, count: number) {
this.productName = name;
this.count = count;
this.value = value;
}
}
如您所见,value
和 count
setter 也负责更新 details
。这简化了组件的逻辑:
products: PropsData[];
allTotal: number = 0;
ngOnInit() {
this.products = [
new PropsData("sugar", 20, 1),
new PropsData("salt", 40, 1),
new PropsData("jackery", 70, 1)
];
this.updateAllTotal();
}
updateCount(product: PropsData) {
product.count++;
this.updateAllTotal();
}
updateAllTotal(): void {
this.allTotal = 0;
this.products.forEach(
(item) => (this.allTotal = this.allTotal + item.details)
);
}