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

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

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

问题

问题

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

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

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

@Component({
  tag: "test-nav-link",
  styleUrl: "test-nav-link.css",
  shadow: true,
})
export class TestNavLink {
  @Prop() href?: string;
  @Prop() label?: string;
  @Prop() target?: string;
  @Prop() rel?: string;
  @Prop() active = false;
  @Prop() icon?: IconList;
  @Prop() iconsize = IconSizeList.md;

  render() {
    return (
      <a
        data-active={this.active}
        href={this.href}
        target={this.target}
        rel={this.rel}
      >
        {this.icon && (
          <icon
            icon={this.icon}
            iconsize={this.iconsize}
            icontype={IconTypeList.text}
          />
        )}
        {this.label}
      </a>
    );
  }
}

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

<test-layout-nav>
  <test-nav-link routerLink="site"
                 routerLinkActive="{{ activeClass }}"
                 label="Site">
  </test-nav-link>
  <test-nav-link routerLink="page"
                 routerLinkActive="{{ activeClass }}"
                 label="Page">
  </test-nav-link>
  <div class="nav-actions" slot="actions">
    <app-search></app-search>
    <settings></settings>
  </div>
</test-layout-nav>

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

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

我尝试过的事情

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

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

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

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

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

<test-nav-link routerLink="site"
               routerLinkActive="{{ activeClass }}"
               (keydown.enter)="onEnter('site')"
               label="Site">
</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:

@Component({
  tag: &quot;test-nav-link&quot;,
  styleUrl: &quot;test-nav-link.css&quot;,
  shadow: true,
})
export class TestNavLink {
  @Prop() href?: string;
  @Prop() label?: string;
  @Prop() target?: string;
  @Prop() rel?: string;
  @Prop() active = false;
  @Prop() icon?: IconList;
  @Prop() iconsize = IconSizeList.md;

  render() {
    return (
      &lt;a
        data-active={this.active}
        href={this.href}
        target={this.target}
        rel={this.rel}
      &gt;
        {this.icon &amp;&amp; (
          &lt;icon
            icon={this.icon}
            iconsize={this.iconsize}
            icontype={IconTypeList.text}
          /&gt;
        )}
        {this.label}
      &lt;/a&gt;
    );
  }
}

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

&lt;test-layout-nav&gt;
  &lt;test-nav-link routerLink=&quot;site&quot;
                 routerLinkActive=&quot;{{ activeClass }}&quot;
                 label=&quot;Site&quot;&gt;
  &lt;/test-nav-link&gt;
  &lt;test-nav-link routerLink=&quot;page&quot;
                 routerLinkActive=&quot;{{ activeClass }}&quot;
                 label=&quot;Page&quot;&gt;
  &lt;/test-nav-link&gt;
  &lt;div class=&quot;nav-actions&quot; slot=&quot;actions&quot;&gt;
    &lt;app-search&gt;&lt;/app-search&gt;
    &lt;settings&gt;&lt;/settings&gt;
  &lt;/div&gt;
&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:

  &lt;test-nav-link routerLink=&quot;site&quot;
                 routerLinkActive=&quot;{{ activeClass }}&quot;
                 (keydown.enter)=&quot;onEnter(&#39;site&#39;)&quot;
                 label=&quot;Site&quot;&gt;
  &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:

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

Or this one, maybe:

&lt;test-nav-link routerLink=&quot;site&quot;
                 routerLinkActive=&quot;{{ activeClass }}&quot;
                 (keydown.enter)=&quot;$any($event.target).click()&quot;
                 label=&quot;Site&quot;&gt;
  &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 :

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

Or this one, maybe :

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

答案2

得分: 1

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

  @Listen('keydown')
  handleKeyDown(ev: KeyboardEvent) {
    if (ev.key === 'Enter') {
      if (this.routerLink !== undefined) {
        this.hostElement.click();
      }
    }
  }

谢谢MGX!

英文:

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

  @Listen(&#39;keydown&#39;)
  handleKeyDown(ev: KeyboardEvent) {
    if (ev.key === &#39;Enter&#39;) {
      if (this.routerLink !== undefined) {
        this.hostElement.click();
      }
    }
  }

Thanks MGX!

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

如何将MySQL表列作为变量放入 :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定