在 Ember.js 中结合 linkTo 和 action 助手
Posted
技术标签:
【中文标题】在 Ember.js 中结合 linkTo 和 action 助手【英文标题】:Combine linkTo and action helpers in Ember.js 【发布时间】:2013-04-14 00:19:11 【问题描述】:我需要在 Ember.js 中结合 linkTo 和操作助手。我的代码是:
#link-to 'index'<span action 'clear'>Clear</span>/link-to
但我想把它做成这样:
#link-to 'index' action 'clear' Clear/link-to
还有:
<li>
#link-to 'support'
<span action 'myAction' 'support'>Support</span>
/link-to
</li>
收件人:
<li>
#link-to 'support' action 'myAction' 'support' Support/link-to
</li>
我怎样才能做到这一点?
解决方案
Check my answer for Ember 2.0 compatible, OK for SEO solution.
【问题讨论】:
可能有点晚了,但是为什么你不能简单地将你的link-to
助手包裹在像 span
这样的其他 html 元素中并在那里触发你想要的操作? Ej:<span action 'yourAction'> link-to 'yourRoute' link text /link-to </span>
这将是 2 个 HTML 元素而不是 1 个。此外,您需要在 CSS 中进行更改。如果有可能在 1 个元素中做到这一点并且 seo 还可以,那么为什么不去做呢? ;)和1件更多的东西。如果你有几十个或几百个这样的链接怎么办。那将是您需要的 HTML 样板的两倍。
好吧,我只是不介意 2 个 html 元素呵呵
【参考方案1】:
这是在 Ember 3.11.0 之后带有 on
修饰符的样子。
<LinkTo
on "click" this.recordMetrics
@route="post.see-all"
@model=@model
@bubbles=false>
Link Me
</LinkTo>
bubbles
仅用于说明 LinkTo API。
https://blog.emberjs.com/ember-3-11-released/
【讨论】:
刚刚又遇到了这个问题......这个解决方案对我不起作用:将on
修饰符添加到LinkTo
组件原因是停止进行转换。 Ember 3.28.6.
这适用于 3.28.8,因为我刚刚将它添加到项目中。我必须确保我调用的方法有动作装饰器,但看起来效果很好。【参考方案2】:
Ember 链接操作插件
这适合 SEO 解决方案!
安装插件
ember install ember-link-action
用法
您可以将关闭操作作为invokeAction
参数传递给link-to
组件:
#link-to 'other-route' invokeAction=(action 'testAction')
Link to another route
/link-to
要将参数传递给操作,您可以使用:
#link-to 'other-route' invokeAction=(action 'testAction' param1 param2)
Link to another route
/link-to
兼容性
自动化测试套件确认插件适用于 1.13 到最新的 Ember 3 版本。
它适用于 Ember 的发行版、测试版和金丝雀版。
Addon GitHub repository. 欢迎投稿。
【讨论】:
【参考方案3】:我喜欢 Cereal Killer 的简单方法,但不幸的是它给我带来了问题。当浏览器导航到另一个路由时,它重新启动 Ember 应用程序。
从 Ember 2.6 开始,以下简单方法可以解决问题:
<span action 'closeNavigationMenu'>
#link-to 'home' preventDefault=false
Go Home
/link-to
</span>
这实现了以下目标:
导航到路线“家” 调用了“closeNavigationMenu”操作 鼠标悬停时,浏览器会显示链接(用于 SEO 和更好的用户体验) 浏览器导航不会导致 Ember 应用重新启动【讨论】:
【参考方案4】:更新:请参阅下方 Michael Lang 对 Ember 1.8.1+ 的评论
Myslik 的答案(根本不使用link-to
,而是使用action
然后transitionToRoute
)的问题在于它对 SEO 无用,搜索引擎机器人什么也看不到。
如果您希望将链接指向的内容编入索引,最简单的方法是在其中放置一个很好的旧<a href=x>
。最好使用link-to
,以便您的链接 URL 与您的路由 URL 保持同步。我使用的解决方案既提供了完成工作的操作,又提供了方便的link-to
来索引页面。
我重写了Ember.LinkView
的一些功能:
Ember.LinkView.reopen(
action: null,
_invoke: function(event)
var action = this.get('action');
if(action)
// There was an action specified (in handlebars) so take custom action
event.preventDefault(); // prevent the browser from following the link as normal
if (this.bubbles === false) event.stopPropagation();
// trigger the action on the controller
this.get('controller').send(action, this.get('actionParam'));
return false;
// no action to take, handle the link-to normally
return this._super(event);
);
然后我可以在 Handlebars 中指定要执行的操作以及传递操作的内容:
<span action 'view' this>
#link-to 'post' action='view' actionParam=this
Post Title: title
/link-to
</span>
在控制器中:
App.PostsIndexController = Ember.ArrayController.extend(
actions:
view: function(post)
this.transitionToRoute('post', post);
这样,当我缓存页面的渲染副本并将其提供给索引机器人时,机器人将看到一个带有 URL 的真实链接并跟随它。
(另请注意,transitionTo
现在已弃用,取而代之的是 transitionToRoute
)
【讨论】:
我不是 SEO 专家。但我简要听说过 Google 使用 JS 框架为网站编制索引的新方法。如果您有使用新的 JS SEO 系统的设置,他们还会查看 href 属性吗? 我认为至少在接下来的几年里,任何未来/待定的解决方案仍然会查看 href 属性。忽略锚标记将是对网络索引方式的重大改变。如果某些搜索机器人找到了运行 JS 的绝妙方法,但我看不出它不起作用,则上述解决方案可能会变得多余。 为了完善这个很好的答案,最好在调用操作之前检查链接是否被禁用(通过 this.get('_isDisabled') )。 感谢您的回答!似乎链接到帮助程序的设计自发布以来可能已更改。在 Ember 1.8.1 中,我不得不替换 this.get('controller').send(action, this.get('actionParam'));用 this.sendAction('action', this.get('actionParam'));为了让动作传播到我的路由控制器。【参考方案5】:这在 1.6.0-beta.5 中运行良好:
<span action "someAction">
#link-to "some.route"
Click Me
/link-to
</span>
链接将发生,然后单击将冒泡到操作处理程序。它已记录在案(尽管是间接的)here。
编辑:更正了打开链接标签中的语法
【讨论】:
这违反了一些 a11y 准则,请不要这样做!【参考方案6】:Ember 的链接到标签使用路由来打开新视图,因此您可以在目标路由的 setupController
方法中而不是在控制器操作中执行您想要放入链接的“动作”属性中的任何功能。
请参阅 Ember 指南中的此处: http://emberjs.com/guides/routing/setting-up-a-controller/
这仅适用于您希望每次访问路由时都执行该操作,而不是使用特定链接。
确保包含controller.set('model', model);
行以及您在其中放置的任何其他内容。
【讨论】:
【参考方案7】:这就是我在 O'Reilly Ember.js 书的演示应用程序中解决此问题的方法:https://github.com/emberjsbook。
您可以在此处查看完整的源代码:https://github.com/emberjsbook/rocknrollcall
在视图中:
#if artistsIsChecked
#if artists.length
<h3>Artists</h3>
<ul class="search-results artists">
#each artists
<li><a action 'viewedArtist' this.enid >name</a></li>
/each
</ul>
/if
/if
还有控制器:
App.SearchResultsController = Em.ObjectController.extend(
actions:
viewedArtist: function(enid)
this.transitionToRoute('artist', enid);
,
viewedSong: function(sid)
this.transitionToRoute('song', sid);
,
needs: ['artists', 'songs'],
artistsIsChecked: true,
songsIsChecked: true,
artists: [],
songs: []
);
【讨论】:
【参考方案8】:遇到同样的问题,我找到了这个简单的解决方案:
#linkTo eng.rent class="external-button"<div class="internal-button" action "updateLangPath" >X</div>/linkTo
然后,管理样式表中的css类external-button和internal-button,我确保“internal-button”覆盖了整个“external-button”区域;这样就不可能在不点击内部按钮的情况下点击外部按钮。
它对我很有效;希望对您有所帮助...
【讨论】:
【参考方案9】:这些组合都不适用于 Ember.js,但您不需要组合这两个助手。为什么不直接使用动作助手,让它冒泡到控制器或路由?在那里你可以在控制器中使用transitionToRoute
或在路由中使用transitionTo
。
例如在控制器中你可以有这样的代码:
App.PostsController = Ember.ArrayController.extend(
clear: function ()
// implement your action here
this.transitionToRoute('index');
);
【讨论】:
为什么在 Fireup ember 教程中他们会这样做 在 Ember.js 的这个时代,您可以注入路由器服务并转换,而不必冒泡到顶部以上是关于在 Ember.js 中结合 linkTo 和 action 助手的主要内容,如果未能解决你的问题,请参考以下文章