Angular:Boolean @Input vs Attribute @Directive - 要使用哪个?

时间:2018-01-24 17:25:28

标签: javascript angular typescript angular-directive angular-components

使用Angular我想要做的是创建一个"指令"这会为我的组件添加一些内容,让myPortlet myHasCloseButtonmyPortlet一个关闭按钮。

<myPortlet myHasCloseButton>...</myPortlet>

我找到了三种选择如何解决这个问题,我不确定哪一个是正确的,或者我错过了更好的选择。

选项1: 创建一个类似

的指令
this.el.nativeElement.querySelector('.myCloseButton').style.visibility = 'visible';
  • 指令的存在启用了语法上令人敬畏的按钮(见上文)。
  • 可以应用于多个myPortlets,可以更灵活地使用。
  • 不允许*ngIf,因此强制每个myPortlet和其他组件带有隐藏的myCloseButton,这种感觉很尴尬,似乎不推荐。
  • 不允许绑定到某个布尔属性。

选项1a: 就像选项1一样,但是给指令一个布尔值@Input来切换可见性的应用。

  • 允许绑定一些布尔属性。
  • 指令的存在已不再足够,现在使用

    ...

选项2: 在适当的位置为myPortlet提供布尔@Input*ngIf指令。

  • 没有必要的关闭按钮。
  • 允许绑定布尔值。
  • 必须为使用它的每个组件单独实施。
  • 指令的存在不再足够,见上文。

选项2b: &#34; Hackily&#34;给出一个字符串@Input,然后检查它是否为空(因为当你输入的名字没有任何内容时会发生什么)并将其视为真。

  • 指令的存在启用了语法上令人敬畏的按钮(见上文)。
  • 不允许绑定到某个布尔属性,除非可以通过将boolean转换为字符串。

选项3: 创建一个实际通过类似

注入myCloseButton的指令
ElementRef.nativeElement.querySelector('.myCloseButton').addComponent(myCloseButton)

[没有经过实际测试的语法,只是一个例子,不确定addComponent是否是正确的函数以及如何使用它]

  • 不知怎的感觉很尴尬,看起来像是不好的做法而且过于复杂。
  • 在Angular Docs中警告使用Elementref,似乎很危险。
  • 强制每个myPortlet和其他组件携带隐藏的myCloseButton容器。
  • myPortlet(或其他组件)无法再控制嵌入式myCloseButton
  • 因此,实现myPortlet与嵌入式myCloseButton之间的沟通可能更加困难(尤其是myCloseButton更复杂的事情。)

所以我的问题是:推荐的方法是哪种?我错过了任何选择吗?任何最佳做法?这些选择都不合适。

1 个答案:

答案 0 :(得分:2)

使用@Input()最适合此用例。

它简单,干净,最重要的是,它允许您动态地确定您的组件是否具有关闭按钮(使用属性指令无法获得的一个很好的功能)。示例(这是非常糟糕的用户体验),但如果您只想让管理员用户拥有关闭按钮该怎么办呢。然后,您可以订阅您的用户服务并设置[hasCloseButton]="userIsAdmin$ | async"。这是一个非常强大的东西,你不能用一个属性指令(用干净的方式)做。

此外,对于测试,您可以直接设置输入(testComponent.hasCloseButton = true),而不必创建测试主机组件并使用指令/一个创建一个案例。

总结一下:使用@Input()将为您提供更大的灵活性并使测试更容易。