由于我们希望保持模板尽可能简单,因此使用标识符声明组件,并从服务中检索数据,而无需显式数据绑定。
<my-awesome-input field="makeDescription" displayItem maxLength="100" size="42" />
所有组件都派生自BaseComponent
,其值字段具有良好的getter和setter:
get value(): any {
return this.contentService.getItemData(this.block, this.field, this.computedIndex);
}
set value(value: any) {
this.contentService.setItemData(this.block, this.field, this.id, value, this.computedIndex);
}
我们还为每个组件提供了许多属性,必须根据其他属性进行设置。这些属性可用于显示组件(CSS类,工具提示,...)。
问题是,由于我们没有使用标准数据绑定,因此当计算的属性值发生变化时,不会触发ngOnChanges。
由于这是技术代码,程序员只需要重复使用提供的组件,我们就可以大量定制这些组件。
我们可能会实现这样的自定义变化检测器:
ngDoCheck() {
const changes: SimpleChanges = {};
let change = false;
this.getFieldsToCheck().forEach(field => {
const v = this[field];
if (!this.firstChanges[field]) {
changes[field] = new SimpleChange(undefined, v, true);
this.firstChanges[field] = true;
this.previousValues[field] = v;
change = true;
} else {
const pv = this.previousValues[field];
if (v !== pv) {
changes[field] = new SimpleChange(pv, v, false);
this.previousValues[field] = v;
change = true;
}
}
});
if (change) {
this.ngOnChanges(changes);
}
}
可能做得更好,但它按预期工作。它与标准@Input和ngOnChanges的行为几乎相同。此外,它可能比标准变化检测器慢。
我们可能会在每个提供的组件中封装一个内部组件,标准数据与[(ngModel)]或[myattribute]绑定。
我没有尝试过这个解决方案,因为它看起来不太好,但它会重用标准机制。
我在Angular 2+开发方面很新,我可能错过了更简单的解决方案。
我渴望得到针对这类问题的任何指针,或对目标解决方案的任何意见。
感谢。