问题的产生: 搜索学习 Angular onPush
相关知识,还原一篇文章中的例子,结果没有出现文章中提到的问题.
onPush检测机制的执行条件是只有当传入的值有变化.简单类型是值变化,而复杂类型是引用变化,才会执行组件内部的state更新然后更新视图。经常使用 xxx.slice()
,这个 xxx
应该是一种什么数据结构 ?
文章中代码如下:
add (): void {
this.employeeList.unshift(new Employee('haha', 15))
this.employeeList = this.employeeList.slice()
}
我还原的this.employeeList
结构如下:
employeeList: Employee[] = [
{
name: "软件开发工程师",
rate: 4,
},
{
name: "业务设计师",
rate: 5,
},
]
也就是说,我还原的代码,没有使用 this.employeeList.slice()
这句,数据就变化了.
原文章: https://zhuanlan.zhihu.com/p/...
恢复文章的例子:
1.Employee.ts
export class Employee {
name: string;
rate: number;
constructor(name, rate) {
this.name = name;
this.rate = rate;
}
}
2.app.component.ts
export class AppComponent {
title = 'hello-angular';
departmentName = 'Front End'
employeeList: Employee[] = [
{
name: "PPQA",
rate: 3,
},
{
name: "软件开发工程师",
rate: 4,
},
{
name: "业务设计师",
rate: 5,
},
{
name: "UI设计师",
rate: 6,
},
{
name: "销售代表",
rate: 7,
},
]
add (): void {
console.log(123)
this.employeeList.push(new Employee('中国航天科工工程总院客户联络代表', Math.floor((Math.random()*10)+30)))
this.employeeList = this.employeeList.slice() // 此行删除,数据也会更新
}
addEnter (name: string): void {
console.log(456)
this.employeeList.unshift(new Employee(name, Math.floor((Math.random()*10)+30)))
this.employeeList = this.employeeList.slice()
}
removeThis (employee: Employee): void {
console.log(employee)
this.employeeList = this.employeeList.filter((item) => {
return !employee.name.includes(item.name)
});
}
}
3.app.component.html
<button (click)="add()">add</button>
<app-employee-list [departmentName]='departmentName' [employeeList]="employeeList" (add)="addEnter($event)" (remove)="removeThis($event)"></app-employee-list>
4.employee-list.component.ts
import { Component, Input, Output, EventEmitter } from "@angular/core";
import { Employee } from './Employee';
const fibonacci = (num: number): number => {
if (num === 1 || num === 2) {
return 1;
}
return fibonacci(num - 1) + fibonacci(num - 2);
}
@Component({
selector: 'employee-list',
templateUrl: './Employee.component.html',
styleUrls: ['./Employee.component.scss']
})
export class EmployeeListComponent {
@Input() departmentName: string
@Input() employeeList: Employee[]
@Output() remove = new EventEmitter<Employee>()
@Output() add = new EventEmitter<string>()
name: string
handleKey (event: any): void {
if (event.keyCode === 13) {
this.add.emit(this.name)
this.name = ''
}
}
handleRemove (employee: Employee): void {
this.remove.emit(employee)
}
calculate (num: number) {
return fibonacci(num)
}
}
5.employee-list.component.html
<div class="employee-container">
<h1>{{ departmentName }}</h1>
<p>
<label for="employee"></label>
<input type="text" id="employee" placeholder="please input a employee name" [(ngModel)]="name" (keydown)="handleKey($event)" />
</p>
<ul>
<li *ngFor="let employee of employeeList">
<span>{{ employee.name }}</span>
<span class="rate">{{ calculate(employee.rate) }}</span>
<button (click)="handleRemove(employee)">delete</button>
</li>
</ul>
</div>