Angular 不提供任何语法糖来控制输入的绑定频率。
但是,您可以控制输入更新时的反应时间。有两种方法,其中一种或两种都可用于获得所需的行为:
- 对Input使用setter并有条件地将更新转发到组件主体或组件的模板。
- 在满足输入时打开或关闭组件中的更改检测
ChangeDetectorRef
。
请注意,关闭更改检测并不意味着不会更新输入。输入将始终更新,因此ngOnChanges
无论更改检测是关闭还是打开都会被调用。但是,如果更改检测关闭,模板将不会针对更新的输入进行更新。请参阅代码框以了解此效果。
示例 1
为了解释上面的第 1 点,请考虑以下几点:
_input1: number;
@Input() set input1(input: number) {
if (this._input1 === undefined || this._input1 === null) {
this._input1 = input;
}
}
在模板中消费
<div>Bound Input1: {{ _input1 }}</div>
_input1
是组件的本地副本,仅在需要时更新,即在上述特定情况下,本地副本仅在之前为null或undefined时更新。input1
是输入属性。这里我们假设一个未定义或空值永远不会被认为是一个有效值,除非input1
传递一个非空 非未定义值,否则我们将认为“绑定一次”没有发生。
示例 2
ChangeDetectorRef
文档摘录:
提供变更检测功能的基类。更改检测树收集要检查更改的所有视图。使用这些方法从树中添加和删除视图,启动更改检测......
所以 ChangeDetectorRef 的方法detach
可以用来从变化检测树中分离一个组件。为了演示上面的第 2 点,以下示例等待所有输入都满足,然后关闭更改检测:
import {
ChangeDetectorRef,
Component,
Input,
OnChanges,
SimpleChanges
} from "@angular/core";
@Component({
selector: "bind-until-all",
template: `
<div>Input1: {{ input1 }}</div>
<div>Input2: {{ input2 }}</div>
<div>Input3: {{ input3 }}</div>
`
})
export class BindUntillAllComponent implements OnChanges {
/**
* We assume that a null or undefined value is not an empty.
* And until a non-empty value is passed to an input, it'll be considered as not-assigned.
*
* Based on the use case, define what is a suitable "empty" value
* and assign that value as the default value to the inputs.
*/
@Input() input1: number;
@Input() input2: number;
@Input() input3: number;
private isDetached: boolean = false;
constructor(private cdr: ChangeDetectorRef) {}
ngOnChanges(changes: SimpleChanges) {
// Check whether all inputs are satisfied i.e. they have non-empty values assigned
// For our case, type === "number" satisfies that the value is non-empty
const areAllInputsSatisfied = [this.input1, this.input2, this.input3].every(
(n) => typeof n === "number"
);
// Stop change detection after triggering the manual change detection once
if (areAllInputsSatisfied && !this.isDetached) {
this.cdr.detectChanges();
this.cdr.detach();
this.isDetached = true;
}
}
}
上面提到的代码框中的实时示例。