gpt4 book ai didi

angular - 使指令 @Input 需要

转载 作者:太空狗 更新时间:2023-10-29 16:48:50 26 4
gpt4 key购买 nike

在 AngularJs 中,我们可以使指令属性成为必需的。我们如何使用 @Input 在 Angular 中做到这一点?文档没有提到它。

例如。

@Component({
selector: 'my-dir',
template: '<div></div>'
})
export class MyComponent {
@Input() a: number; // Make this a required attribute. Throw an exception if it doesn't exist.
@Input() b: number;
}

最佳答案

官方解决方案

作为answered作者:Ryan Miglavs – Angular 的巧妙用法 selectors解决了这个问题。

/** Note: requires the [a] attribute to be passed */
@Component({
selector: 'my-dir[a]', // <-- use attribute selector along with tag to ensure both tag name and attribute are used to "select" element by Angular in DOM
});
export class MyComponent {
@Input() a: number;
}

在大多数情况下,我个人更喜欢这种解决方案,因为它不需要在编码期间进行任何额外的工作。但是,它也有一些缺点:

  • 无法理解抛出的错误中缺少什么参数
  • 错误正如它所说的那样令人困惑,当只缺少一些参数时,Angular 无法识别该标记

如上所示,通过在 @Component 装饰器上方添加装饰性注释,可以部分改善这两种负面情况,大多数编辑器会显示组件名称的任何工具提示信息。不过,它对 Angular 错误输出没有帮助。


对于替代解决方案——请看下面,它们需要一些额外的编码,但没有上述缺点。


所以,这是我使用 getters/setters 的解决方案。恕我直言,这是一个非常优雅的解决方案,因为一切都在一个地方完成,而且这个解决方案不需要 OnInit 依赖。

解决方案#2

Component({
selector: 'my-dir',
template: '<div></div>',
});
export class MyComponent {
@Input()
get a() {
throw new Error('Attribute "a" is required');
}
set a(value: number) {
Object.defineProperty(this, 'a', {
value,
writable: true,
configurable: true,
});
}
}

解决方案#3:

使用装饰器可以更容易完成。所以,你在你的应用程序中定义了这样一个装饰器:

function Required(target: object, propertyKey: string) {
Object.defineProperty(target, propertyKey, {
get() {
throw new Error(`Attribute ${propertyKey} is required`);
},
set(value) {
Object.defineProperty(target, propertyKey, {
value,
writable: true,
configurable: true,
});
},
configurable: true
});
}

稍后在您的类(class)中,您只需按要求标记您的属性,如下所示:

Component({
selector: 'my-dir',
template: '<div></div>',
});
export class MyComponent {
@Input() @Required a: number;
}

解释:

如果定义了属性 a - 属性 a 的 setter 将覆盖自身并使用传递给属性的值。否则 - 在组件初始化之后 - 第一次你想在你的类或模板中使用属性 a - 将抛出错误。

注意:getters/setters 在 Angular 的组件/服务等中运行良好,像这样使用它们是安全的。但是在将这种方法用于 Angular 之外的纯类时要小心。问题是如何打字 transpiles getters/setters到 ES5 - 它们被分配给类的 prototype 属性。在这种情况下,我们会改变原型(prototype)属性,该属性对于类的所有实例都是相同的。意味着我们可以得到这样的东西:

const instance1 = new ClassStub();
instance1.property = 'some value';
const instance2 = new ClassStub();
console.log(instance2.property); // 'some value'

关于angular - 使指令 @Input 需要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35528395/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com