英文:
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添加到组件
我尝试将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: "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>
);
}
}
And then I can use this in the navbar for one of my apps as so:
<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>
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
Adding routerLink to the component
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:
<test-nav-link routerLink="site"
routerLinkActive="{{ activeClass }}"
(keydown.enter)="onEnter('site')"
label="Site">
</test-nav-link>
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 <a>
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:
<test-nav-link #link routerLink="site"
routerLinkActive="{{ activeClass }}"
(keydown.enter)="link.click()"
label="Site">
</test-nav-link>
Or this one, maybe:
<test-nav-link routerLink="site"
routerLinkActive="{{ activeClass }}"
(keydown.enter)="$any($event.target).click()"
label="Site">
</test-nav-link>
英文:
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 :
<test-nav-link #link routerLink="site"
routerLinkActive="{{ activeClass }}"
(keydown.enter)="link.click()"
label="Site">
</test-nav-link>
Or this one, maybe :
<test-nav-link routerLink="site"
routerLinkActive="{{ activeClass }}"
(keydown.enter)="$any($event.target).click()"
label="Site">
</test-nav-link>
答案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('keydown')
handleKeyDown(ev: KeyboardEvent) {
if (ev.key === 'Enter') {
if (this.routerLink !== undefined) {
this.hostElement.click();
}
}
}
Thanks MGX!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论