将另一个库中的自定义角度组件设置为可以使用”Enter”键单击。

huangapple go评论102阅读模式
英文:

Making a custom angular component from another library clickable with "enter" key

问题

问题

tl;dr: 我正在创建的一个角度组件无法通过回车键点击。

我有一个使用stencil构建的库,它定义并创建了一堆要在一组应用程序中使用的角度组件。

我试图创建一个导航链接,以从该库中使用:

  1. @Component({
  2. tag: "test-nav-link",
  3. styleUrl: "test-nav-link.css",
  4. shadow: true,
  5. })
  6. export class TestNavLink {
  7. @Prop() href?: string;
  8. @Prop() label?: string;
  9. @Prop() target?: string;
  10. @Prop() rel?: string;
  11. @Prop() active = false;
  12. @Prop() icon?: IconList;
  13. @Prop() iconsize = IconSizeList.md;
  14. render() {
  15. return (
  16. <a
  17. data-active={this.active}
  18. href={this.href}
  19. target={this.target}
  20. rel={this.rel}
  21. >
  22. {this.icon && (
  23. <icon
  24. icon={this.icon}
  25. iconsize={this.iconsize}
  26. icontype={IconTypeList.text}
  27. />
  28. )}
  29. {this.label}
  30. </a>
  31. );
  32. }
  33. }

然后,我可以在我的一个应用程序的导航栏中使用它,如下所示:

  1. <test-layout-nav>
  2. <test-nav-link routerLink="site"
  3. routerLinkActive="{{ activeClass }}"
  4. label="Site">
  5. </test-nav-link>
  6. <test-nav-link routerLink="page"
  7. routerLinkActive="{{ activeClass }}"
  8. label="Page">
  9. </test-nav-link>
  10. <div class="nav-actions" slot="actions">
  11. <app-search></app-search>
  12. <settings></settings>
  13. </div>
  14. </test-layout-nav>

如果使用href(即在我们没有访问权限的某些空间之一),则此方法有效。

当使用角度的routerLink时,不起作用 - 它可以正确呈现,我可以按按钮,甚至可以通过Tab键导航到它,但当我按Enter键时,它不起作用。

我尝试过的事情

我尝试将routerLink添加为组件上的附加@Prop,然后更改href为:

href={this.href ? this.href | this.routerLink}

这使其可以点击,但然后页面会加载两次;一次通过routerLink,一次通过href。

在使用code的地方添加keydown.enter

我可以更改导航使用如下:

  1. <test-nav-link routerLink="site"
  2. routerLinkActive="{{ activeClass }}"
  3. (keydown.enter)="onEnter('site')"
  4. label="Site">
  5. </test-nav-link>

这可以工作,但感觉它添加了大量样板代码;拥有单独的组件库的目的是您只需编写这些内容一次,然后可以在任何地方使用组件。

其他

我尝试了一些与tabindex=-1有关的奇怪操作,以查看是否可以强制锚元素可点击,但是,没有成功。


有什么建议吗?我唯一剩下的想法是放弃这个组件的想法,回到只使用<a>

英文:

The problem

tl;dr: An angular component I'm creating isn't clickable via enter.

I have a library built with stencil that defines & creates a bunch of angular components to use across a set of apps.

I'm trying to create a navigation link to use from that library:

  1. @Component({
  2. tag: &quot;test-nav-link&quot;,
  3. styleUrl: &quot;test-nav-link.css&quot;,
  4. shadow: true,
  5. })
  6. export class TestNavLink {
  7. @Prop() href?: string;
  8. @Prop() label?: string;
  9. @Prop() target?: string;
  10. @Prop() rel?: string;
  11. @Prop() active = false;
  12. @Prop() icon?: IconList;
  13. @Prop() iconsize = IconSizeList.md;
  14. render() {
  15. return (
  16. &lt;a
  17. data-active={this.active}
  18. href={this.href}
  19. target={this.target}
  20. rel={this.rel}
  21. &gt;
  22. {this.icon &amp;&amp; (
  23. &lt;icon
  24. icon={this.icon}
  25. iconsize={this.iconsize}
  26. icontype={IconTypeList.text}
  27. /&gt;
  28. )}
  29. {this.label}
  30. &lt;/a&gt;
  31. );
  32. }
  33. }

And then I can use this in the navbar for one of my apps as so:

  1. &lt;test-layout-nav&gt;
  2. &lt;test-nav-link routerLink=&quot;site&quot;
  3. routerLinkActive=&quot;{{ activeClass }}&quot;
  4. label=&quot;Site&quot;&gt;
  5. &lt;/test-nav-link&gt;
  6. &lt;test-nav-link routerLink=&quot;page&quot;
  7. routerLinkActive=&quot;{{ activeClass }}&quot;
  8. label=&quot;Page&quot;&gt;
  9. &lt;/test-nav-link&gt;
  10. &lt;div class=&quot;nav-actions&quot; slot=&quot;actions&quot;&gt;
  11. &lt;app-search&gt;&lt;/app-search&gt;
  12. &lt;settings&gt;&lt;/settings&gt;
  13. &lt;/div&gt;
  14. &lt;/test-layout-nav&gt;

This works if you use href (i.e. in one of the spaces where we don't have access to angular).

This does not work when using angular's routerLink - it renders fine, I can press the button, I can even tab to it, but when I press enter, it doesn't act as a link.

What I've tried

I've tried adding routerLink as an additional @Prop on the component, and then changing the href to:

href={this.href ? this.href | this.routerLink}

This makes it clickable, but then the page loads twice; once via routerLink, once via href.

Adding keydown.enter where code is used

I can change the nav usage to look as follows:

  1. &lt;test-nav-link routerLink=&quot;site&quot;
  2. routerLinkActive=&quot;{{ activeClass }}&quot;
  3. (keydown.enter)=&quot;onEnter(&#39;site&#39;)&quot;
  4. label=&quot;Site&quot;&gt;
  5. &lt;/test-nav-link&gt;

This works, but it feels like it adds a lot of boilerplate; the point of having a separate library of components is that you need to write stuff like this once, and then can use the components everywhere.

Other

I tried some weird stuff with tabindex=-1 to see if I could force the anchor element to be clickable, but yeah, no dice.


Any advice? The only thing I can think of left is scrap this component as an idea and go back to using &lt;a&gt; on its own.

答案1

得分: 1

If you look at the documentation, you will see that the routerLink is actually a directive that manages the clicks for you (line 267~ish)

So, given that, you can probably try to trigger a click when you press enter:

  1. &lt;test-nav-link #link routerLink=&quot;site&quot;
  2. routerLinkActive=&quot;{{ activeClass }}&quot;
  3. (keydown.enter)=&quot;link.click()&quot;
  4. label=&quot;Site&quot;&gt;
  5. &lt;/test-nav-link&gt;

Or this one, maybe:

  1. &lt;test-nav-link routerLink=&quot;site&quot;
  2. routerLinkActive=&quot;{{ activeClass }}&quot;
  3. (keydown.enter)=&quot;$any($event.target).click()&quot;
  4. label=&quot;Site&quot;&gt;
  5. &lt;/test-nav-link&gt;
英文:

If you look at the documentation, you will see that the routerLink is actually a directive that manages the clicks for you (line 267~ish)

So, given that, you can probably try to trigger a click when you press enter :

  1. &lt;test-nav-link #link routerLink=&quot;site&quot;
  2. routerLinkActive=&quot;{{ activeClass }}&quot;
  3. (keydown.enter)=&quot;link.click()&quot;
  4. label=&quot;Site&quot;&gt;
  5. &lt;/test-nav-link&gt;

Or this one, maybe :

  1. &lt;test-nav-link routerLink=&quot;site&quot;
  2. routerLinkActive=&quot;{{ activeClass }}&quot;
  3. (keydown.enter)=&quot;$any($event.target).click()&quot;
  4. label=&quot;Site&quot;&gt;
  5. &lt;/test-nav-link&gt;

答案2

得分: 1

要添加到MGX上面的帖子中,这很容易映射到模板库中:

  1. @Listen('keydown')
  2. handleKeyDown(ev: KeyboardEvent) {
  3. if (ev.key === 'Enter') {
  4. if (this.routerLink !== undefined) {
  5. this.hostElement.click();
  6. }
  7. }
  8. }

谢谢MGX!

英文:

To add to MGX's post above, this is pretty easy to map to the stencil library:

  1. @Listen(&#39;keydown&#39;)
  2. handleKeyDown(ev: KeyboardEvent) {
  3. if (ev.key === &#39;Enter&#39;) {
  4. if (this.routerLink !== undefined) {
  5. this.hostElement.click();
  6. }
  7. }
  8. }

Thanks MGX!

huangapple
  • 本文由 发表于 2023年6月27日 17:44:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76563590.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定