Angular:布尔值@Input 与属性@Directive - 使用哪个?
Angular: Boolean @Input vs Attribute @Directive - which to use?
我想使用 Angular 做的是创建一个 "directive" 来为我的组件添加一些东西,假设 myPortlet
和 myHasCloseButton
给出 myPortlet
一个关闭按钮。
<myPortlet myHasCloseButton>...</myPortlet>
我找到了三种解决方法,但我不确定哪一种是正确的,或者我是否错过了更好的选择。
选项 1:
创建一个执行类似
的指令
this.el.nativeElement.querySelector('.myCloseButton').style.visibility = 'visible';
- 指令的存在启用语法上很棒的按钮(见上文)。
- 可以应用到比 myPortlets 更灵活的用途。
- 不允许
*ngIf
,因此迫使每个 myPortlet
和其他组件携带一个隐藏的 myCloseButton
,这感觉很尴尬,似乎不推荐。
- 不允许绑定到某些布尔值 属性。
选项 1a:
就像选项 1 一样,但是给指令一个布尔值 @Input
来切换可见性的应用。
- 允许绑定一些布尔值属性。
指令的存在不再足够,现在使用
...
选项 2:
在正确的位置给 myPortlet 一个布尔值 @Input
和一个 *ngIf
指令。
- 在不需要的地方不生成关闭按钮。
- 允许绑定布尔值。
- 必须为使用它的每个组件单独实施。
- 指令的存在不再足够,见上文。
选项 2b:
"Hackily" 给出一个字符串 @Input
并检查它是否为空(因为这就是当您只给出输入名称而后面没有任何内容时发生的情况)并将其视为 true。
- 指令的存在启用语法上很棒的按钮(见上文)。
- 不允许绑定到某些布尔值 属性 除非将布尔值类型转换为字符串。
选项 3:
创建一个指令,它实际上通过
之类的东西注入 myCloseButton
ElementRef.nativeElement.querySelector('.myCloseButton').addComponent(myCloseButton)
[没有实际测试过的语法,只是一个例子,不确定 addComponent 是否是正确的函数以及如何使用它]
- 不知何故感觉很尴尬,似乎是不好的做法并且过于复杂。
- 在 Angular 文档中警告不要使用
Elementref
,看起来很危险。
- 强制每个
myPortlet
和其他组件携带一个隐藏的 myCloseButton
容器。
myPortlet
(或其他组件)不再控制嵌入的 myCloseButton
.
- 因此,
myPortlet
和嵌入式 myCloseButton
之间的通信可能会更加困难(尤其是 myCloseButton
更复杂)。
所以我的问题是:推荐的方法是什么?我错过了任何选择吗?有什么最佳做法吗? None 这些选项感觉不错。
使用 @Input()
最适合此用例。
它简单、干净,最重要的是,它允许您动态地确定您的组件是否有关闭按钮(属性指令无法获得的一个很好的功能) .示例(这是糟糕的 UX),但是如果您只想允许管理员用户有一个关闭按钮怎么办。然后,您可以订阅您的用户服务并设置 [hasCloseButton]="userIsAdmin$ | async"
。这是使用属性指令无法(以干净的方式)做的非常强大的事情。
此外,对于测试,您可以直接设置输入 (testComponent.hasCloseButton = true
),而不必创建一个测试主机组件并创建一个有指令的案例/一个没有指令的案例。
总而言之:使用 @Input()
将为您提供更大的灵活性并使测试更容易。
我想使用 Angular 做的是创建一个 "directive" 来为我的组件添加一些东西,假设 myPortlet
和 myHasCloseButton
给出 myPortlet
一个关闭按钮。
<myPortlet myHasCloseButton>...</myPortlet>
我找到了三种解决方法,但我不确定哪一种是正确的,或者我是否错过了更好的选择。
选项 1: 创建一个执行类似
的指令this.el.nativeElement.querySelector('.myCloseButton').style.visibility = 'visible';
- 指令的存在启用语法上很棒的按钮(见上文)。
- 可以应用到比 myPortlets 更灵活的用途。
- 不允许
*ngIf
,因此迫使每个myPortlet
和其他组件携带一个隐藏的myCloseButton
,这感觉很尴尬,似乎不推荐。 - 不允许绑定到某些布尔值 属性。
选项 1a:
就像选项 1 一样,但是给指令一个布尔值 @Input
来切换可见性的应用。
- 允许绑定一些布尔值属性。
指令的存在不再足够,现在使用
...
选项 2:
在正确的位置给 myPortlet 一个布尔值 @Input
和一个 *ngIf
指令。
- 在不需要的地方不生成关闭按钮。
- 允许绑定布尔值。
- 必须为使用它的每个组件单独实施。
- 指令的存在不再足够,见上文。
选项 2b:
"Hackily" 给出一个字符串 @Input
并检查它是否为空(因为这就是当您只给出输入名称而后面没有任何内容时发生的情况)并将其视为 true。
- 指令的存在启用语法上很棒的按钮(见上文)。
- 不允许绑定到某些布尔值 属性 除非将布尔值类型转换为字符串。
选项 3: 创建一个指令,它实际上通过
之类的东西注入 myCloseButtonElementRef.nativeElement.querySelector('.myCloseButton').addComponent(myCloseButton)
[没有实际测试过的语法,只是一个例子,不确定 addComponent 是否是正确的函数以及如何使用它]
- 不知何故感觉很尴尬,似乎是不好的做法并且过于复杂。
- 在 Angular 文档中警告不要使用
Elementref
,看起来很危险。 - 强制每个
myPortlet
和其他组件携带一个隐藏的myCloseButton
容器。 myPortlet
(或其他组件)不再控制嵌入的myCloseButton
.- 因此,
myPortlet
和嵌入式myCloseButton
之间的通信可能会更加困难(尤其是myCloseButton
更复杂)。
所以我的问题是:推荐的方法是什么?我错过了任何选择吗?有什么最佳做法吗? None 这些选项感觉不错。
使用 @Input()
最适合此用例。
它简单、干净,最重要的是,它允许您动态地确定您的组件是否有关闭按钮(属性指令无法获得的一个很好的功能) .示例(这是糟糕的 UX),但是如果您只想允许管理员用户有一个关闭按钮怎么办。然后,您可以订阅您的用户服务并设置 [hasCloseButton]="userIsAdmin$ | async"
。这是使用属性指令无法(以干净的方式)做的非常强大的事情。
此外,对于测试,您可以直接设置输入 (testComponent.hasCloseButton = true
),而不必创建一个测试主机组件并创建一个有指令的案例/一个没有指令的案例。
总而言之:使用 @Input()
将为您提供更大的灵活性并使测试更容易。