当使用ngFor
循环模板中的数组时,将其与trackBy
函数一起使用,该函数将为每个项返回唯一标识符。
当数组更改时,Angular会重新呈现整个DOM树。如果你使用trackBy
,Angular将知道哪个元素已经改变,并且只会对该特定元素进行DOM更改。
例如:
{{item}}
优化为:
//在模板中
{{item}}
//在组件
trackByFn(index,item)中{
return item.id; 对应项目唯一的ID
}
避免从组件订阅observable,而是从模板订阅observable。
async
管道可以自动取消订阅,不再需要手动取消订阅,使代码更简单。忘记取消订阅会导致内存泄漏。通过使用lint规则来检测未订阅的可观察量,也可以减轻这种风险。
这也会阻止组件成为有状态,并引入数据在订阅之外变异的错误。
例如:
// template
{{ textToDisplay }}
// component
iAmAnObservable
.pipe(
map(value => value.item),
takeUntil(this._destroyed$)
)
.subscribe(item => this.textToDisplay = item);
优化为:
// template
{{ textToDisplay$ | async }}
// component
this.textToDisplay$ = iAmAnObservable
.pipe(
map(value => value.item)
);
善用枚举,以在编译时发现错误。ng-zorro-antd源码中几乎在所有暴露@Input(): String的地方使用了此条规则。
例如:
private myStringValue:string;
if(itShouldHaveFirstValue){
myStringValue ='First';
} else {
myStringValue ='Second'
}
优化为:
private myStringValue: 'First' | 'Second';
if (itShouldHaveFirstValue) {
myStringValue = 'First';
} else {
myStringValue = 'Other'
}
// This will give the below error
Type '"Other"' is not assignable to type '"First" | "Second"'
(property) AppComponent.myValue: "First" | "Second"
Don't Repeat Yourself! 这是新手程序员容易犯的错误之一。我在公司检视其他同事的代码时,经常发现其代码中包含两段几乎相同的代码,甚至两个几乎相同的组件!
在我刚学编程时我就发现,使用复制粘贴产生相似的代码,不仅容易产生难找的bug,而且在修改时难以下手。
在这些情况下,使用各种手段抽象、提取重复代码。这意味着只需要改变一个地方,测试一件事。将较少的重复代码发送给用户意味着应用程序将更快。
提炼代码的过程不仅仅能锻炼逻辑能力,也能在这个过程中学到一些新知识。
例如:
@Component({
selector: 'person',
template: `
{{ form.valid ? 'valid' : 'invalid' }}
`,
})
export class PersonComponent {
form = this.formBuilder.group({
name: ['', Validators.required],
contactInfo: [''],
allergies: [''],
})
constructor(private formBuilder: FormBuilder) {}
}
这个表单如果想修改Require验证逻辑在其他地方使用,应该怎么做?
提供一种思路,使用不同的属性型指令提供不同的改装逻辑。
优化后:
@Directive({
selector: 'person[stage-one]',
})
export class StageOneDirective {
constructor(host: PersonComponent) {
host.form.get('contactInfo').setValidators([Validators.required])
}
}
@Directive({
selector: 'person[stage-two]',
})
export class StageTwoDirective {
constructor(host: PersonComponent) {
host.form.get('contactInfo').setValidators([Validators.required])
host.form.get('allergies').setValidators([Validators.required])
}
}