在 Octane 中向 LinkTo 添加额外的操作
Add Extra Actions to LinkTo in Octane
我有一个带有 link 的下拉菜单,单击 link 时我希望关闭菜单。
类似于(a11y/i18n 截断):
<ul class="menu">
<li>
<LinkTo @route="myprofile">
Profile
</LinkTo>
</li>
<li>
<LinkTo @route="logout">
Logout
</LinkTo>
</li>
</ul>
我想向 link 添加一个额外的点击处理程序,例如:
<ul class="menu">
<li>
<LinkTo @route="myprofile" {{on "click" this.closeMenu}}>
Profile
</LinkTo>
</li>
<li>
<LinkTo @route="logout" {{on "click" this.closeMenu}}>
Logout
</LinkTo>
</li>
</ul>
然而,这使得 LinkTo
变得毫无用处,因为它会重新加载页面,就像跟随 link 而不是转换到新路线一样。我们目前正在使用 hember-link-action 执行此操作,但我很想找到一种更惯用的方法来解决此问题。
如果您需要执行额外的逻辑,您可以在操作中实现重定向,而不是使用 LinkTo
助手。为此,您需要将 RouterService
注入到您的组件中,然后调用它的 transitionTo
方法。类似于:
export default class ExampleComponent extends Component {
@service router;
@action
navigate(route) {
this.menuExpanded = false;
this.router.transitionTo(route);
}
}
请注意,还有来自 Route 的 transitionTo()
方法和来自 Controller 的 transitionToRoute()
方法,它们的行为类似于 LinkTo
助手。但是现在不推荐使用这些方法,使用 RouterService
是在 js 代码中进行转换的 recommended 惯用方式。
我已经编写了一个组件来主要处理这个问题,但我很确定 LinkTo
中有更多的边缘情况然后我已经涵盖(例如它不涵盖通过的模型或型号列表)。我将其命名为 <LinkToWithAction />
,它看起来像:
<a href={{this.href}} class={{if this.isActive "active"}} {{on "click" this.navigate}} >
{{yield}}
</a>
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
export default class LinkToWithActionComponent extends Component {
@service router;
get href() {
return this.router.urlFor(this.args.route, {
queryParams: this.queryParams,
});
}
get isActive() {
return this.router.isActive(this.args.route);
}
get queryParams() {
return this.args.queryParams ?? {};
}
@action
navigate(evt) {
evt.preventDefault();
this.args.action();
this.router.transitionTo(this.args.route, {
queryParams: this.queryParams,
});
}
}
它被称为:
<LinkToWithAction
@route="mymaterials"
@action={{set this.isOpen false}}
@queryParams={{hash course=null}}
>
{{t "general.myprofile"}}
</LinkToWithAction>
这个 issue 和 transitionTo
会在调用 URL 时将未设置的 queryParams 添加到 URL,这会影响 public 路由器服务,这让这变得更加烦人。内置组件使用不存在这种行为的私有内部路由器,使用该私有服务可能值得,但现在我们将接受传递查询参数。
我有一个带有 link 的下拉菜单,单击 link 时我希望关闭菜单。
类似于(a11y/i18n 截断):
<ul class="menu">
<li>
<LinkTo @route="myprofile">
Profile
</LinkTo>
</li>
<li>
<LinkTo @route="logout">
Logout
</LinkTo>
</li>
</ul>
我想向 link 添加一个额外的点击处理程序,例如:
<ul class="menu">
<li>
<LinkTo @route="myprofile" {{on "click" this.closeMenu}}>
Profile
</LinkTo>
</li>
<li>
<LinkTo @route="logout" {{on "click" this.closeMenu}}>
Logout
</LinkTo>
</li>
</ul>
然而,这使得 LinkTo
变得毫无用处,因为它会重新加载页面,就像跟随 link 而不是转换到新路线一样。我们目前正在使用 hember-link-action 执行此操作,但我很想找到一种更惯用的方法来解决此问题。
如果您需要执行额外的逻辑,您可以在操作中实现重定向,而不是使用 LinkTo
助手。为此,您需要将 RouterService
注入到您的组件中,然后调用它的 transitionTo
方法。类似于:
export default class ExampleComponent extends Component {
@service router;
@action
navigate(route) {
this.menuExpanded = false;
this.router.transitionTo(route);
}
}
请注意,还有来自 Route 的 transitionTo()
方法和来自 Controller 的 transitionToRoute()
方法,它们的行为类似于 LinkTo
助手。但是现在不推荐使用这些方法,使用 RouterService
是在 js 代码中进行转换的 recommended 惯用方式。
我已经编写了一个组件来主要处理这个问题,但我很确定 LinkTo
中有更多的边缘情况然后我已经涵盖(例如它不涵盖通过的模型或型号列表)。我将其命名为 <LinkToWithAction />
,它看起来像:
<a href={{this.href}} class={{if this.isActive "active"}} {{on "click" this.navigate}} >
{{yield}}
</a>
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
export default class LinkToWithActionComponent extends Component {
@service router;
get href() {
return this.router.urlFor(this.args.route, {
queryParams: this.queryParams,
});
}
get isActive() {
return this.router.isActive(this.args.route);
}
get queryParams() {
return this.args.queryParams ?? {};
}
@action
navigate(evt) {
evt.preventDefault();
this.args.action();
this.router.transitionTo(this.args.route, {
queryParams: this.queryParams,
});
}
}
它被称为:
<LinkToWithAction
@route="mymaterials"
@action={{set this.isOpen false}}
@queryParams={{hash course=null}}
>
{{t "general.myprofile"}}
</LinkToWithAction>
这个 issue 和 transitionTo
会在调用 URL 时将未设置的 queryParams 添加到 URL,这会影响 public 路由器服务,这让这变得更加烦人。内置组件使用不存在这种行为的私有内部路由器,使用该私有服务可能值得,但现在我们将接受传递查询参数。