我的组件通常以具有多个 @Input
和 @Output
属性开始。当我添加属性时,切换到单个配置对象作为输入似乎更清晰。
例如,这是一个具有多个输入和输出的组件:
export class UsingEventEmitter implements OnInit {
@Input() prop1: number;
@Output() prop1Change = new EventEmitter<number>();
@Input() prop2: number;
@Output() prop2Change = new EventEmitter<number>();
ngOnInit() {
// Simulate something that changes prop1
setTimeout(() => this.prop1Change.emit(this.prop1 + 1));
}
}
及其用法:
export class AppComponent {
prop1 = 1;
onProp1Changed = () => {
// prop1 has already been reassigned by using the [(prop1)]='prop1' syntax
}
prop2 = 2;
onProp2Changed = () => {
// prop2 has already been reassigned by using the [(prop2)]='prop2' syntax
}
}
模板:
<using-event-emitter
[(prop1)]='prop1'
(prop1Change)='onProp1Changed()'
[(prop2)]='prop2'
(prop2Change)='onProp2Changed()'>
</using-event-emitter>
随着属性数量的增加,似乎切换到单个配置对象可能会更简洁。例如,这是一个采用单个配置对象的组件:
export class UsingConfig implements OnInit {
@Input() config;
ngOnInit() {
// Simulate something that changes prop1
setTimeout(() => this.config.onProp1Changed(this.config.prop1 + 1));
}
}
及其用法:
export class AppComponent {
config = {
prop1: 1,
onProp1Changed(val: number) {
this.prop1 = val;
},
prop2: 2,
onProp2Changed(val: number) {
this.prop2 = val;
}
};
}
模板:
<using-config [config]='config'></using-config>
现在我可以通过多层嵌套组件传递配置对象引用。使用配置的组件将调用回调,如 config.onProp1Changed(...)
,这会导致配置对象重新分配新值。所以看起来我们仍然有单向数据流。此外,添加和删除属性不需要更改中间层。
将单个配置对象作为组件的输入而不是将多个输入和输出作为输入有任何缺点吗?像这样避免使用 @Output
和 EventEmitter
会导致以后可能会遇到的任何问题吗?
最佳答案
就个人而言,如果我发现我需要超过 4 个输入+输出,我会再次检查我创建组件的方法,也许它应该不止一个组件,但我做错了什么。 无论如何,即使我需要那么多输入和输出,我也不会在一个配置中完成,原因如下:
1- 很难知道输入和输出中应该包含什么,如下所示: (考虑一个带有 html 输入元素和标签的组件)
想象一下,如果您只有这个组件的 3 个,您应该在 1 或 2 个月后回来从事这个项目,或者其他人会与您合作或使用您的代码!。 真的很难理解您的代码。
2- 缺乏表现。 Angular 观察单个变量而不是观察数组或对象要便宜得多。除了考虑我在第一个例子中给你的例子,为什么你应该强制跟踪可能永远不会改变的标签以及总是在变化的值。
3- 更难跟踪变量和调试。 angular 本身带有难以调试的令人困惑的错误,我为什么要让它更难。对我来说,一个一个地跟踪和修复任何错误的输入或输出比在一堆数据中的一个配置变量中更容易。
就我个人而言,我更喜欢将我的组件分解成尽可能小的组件并测试每个组件。然后用小组件制造更大的组件,而不是只有一个大组件。
更新: 我将此方法用于一次输入并且没有更改数据(如标签)
@Component({
selector: 'icon-component',
templateUrl: './icon.component.html',
styleUrls: ['./icon.component.scss'],
inputs: ['name', 'color']
});
export class IconComponent implements OnInit {
name: any;
color: any;
ngOnInit() {
}
}
HTML:
<icon-component name="fa fa-trash " color="white"></icon-component>
使用此方法,angular 不会跟踪组件内部或外部的任何更改。 但是使用 @input 方法,如果您的变量在父组件中发生变化,您也会在组件内部发生变化。
关于javascript - 将 Angular 组件从许多输入/输出重构为单个配置对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47743281/