javascript 在 Ember.js 中结合 linkTo 和动作助手
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16124381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Combine linkTo and action helpers in Ember.js
提问by Daniel Kmak
I need to combine linkTo and action helpers in Ember.js. My code is:
我需要在 Ember.js 中结合 linkTo 和动作助手。我的代码是:
{{#link-to 'index'}}<span {{action 'clear'}}>Clear</span>{{/link-to}}
But I would like to make this something like this:
但我想让它像这样:
{{#link-to 'index' {{action 'clear'}} }}Clear{{/link-to}}
And also:
并且:
<li>
{{#link-to 'support'}}
<span {{action 'myAction' 'support'}}>Support</span>
{{/link-to}}
</li>
To:
到:
<li>
{{#link-to 'support' {{action 'myAction' 'support'}} }}Support{{/link-to}}
</li>
How can I achieve this?
我怎样才能做到这一点?
Solution
解决方案
Check my answer for Ember 2.0 compatible, OK for SEO solution.
采纳答案by Daniel Kmak
Ember Link Action addon
Ember 链接操作插件
This is OK for SEO solution!
这对于 SEO 解决方案来说没问题!
Install addon
安装插件
ember install ember-link-action
Usage
用法
You can pass closure action as invokeAction
param to {{link-to}}
component:
您可以将关闭操作作为invokeAction
参数传递给{{link-to}}
组件:
{{#link-to 'other-route' invokeAction=(action 'testAction')}}
Link to another route
{{/link-to}}
To pass parameters to action you can use:
要将参数传递给操作,您可以使用:
{{#link-to 'other-route' invokeAction=(action 'testAction' param1 param2)}}
Link to another route
{{/link-to}}
Compatibility
兼容性
Automated test suite confirms that addon works with 1.13 up to latest Ember 3 releases.
自动化测试套件确认插件适用于 1.13 至最新的 Ember 3 版本。
It works with a release, beta and canary versions of Ember.
它适用于 Ember 的发行版、测试版和金丝雀版本。
Addon GitHub repository.Contributions are welcome.
插件 GitHub 存储库。欢迎投稿。
回答by Noland
Update:See Michael Lang's comment below for Ember 1.8.1+
更新:请参阅下面 Michael Lang 对 Ember 1.8.1+ 的评论
The problem with Myslik's answer (not using link-to
at all but instead using an action
and then transitionToRoute
) is that it's useless for SEO, search engine bots will see nothing.
Myslik 的答案(根本不使用link-to
,而是使用action
and then transitionToRoute
)的问题在于它对SEO 没用,搜索引擎机器人什么也看不到。
If you want what your link is pointing to to be indexed, it's easiest to have a good old <a href=x>
in there. It's best to use link-to
so that your link URLs are kept in sync with your route URLs. The solution I use gives both an action to do the work and a handy link-to
to index the pages.
如果您希望将链接指向的内容编入索引,则最容易<a href=x>
在其中放置一个好的旧链接。最好使用它,link-to
以便您的链接 URL 与您的路由 URL 保持同步。我使用的解决方案既提供了一个操作来完成工作,又提供了一个方便link-to
的索引页面。
I override some functionality of Ember.LinkView
:
我覆盖了以下功能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);
}
});
Then I can specify which action to take and what to pass the action in Handlebars:
然后我可以在 Handlebars 中指定要执行的操作以及传递操作的内容:
<span {{action 'view' this}}>
{{#link-to 'post' action='view' actionParam=this}}
Post Title: {{title}}
{{/link-to}}
</span>
In the controller:
在控制器中:
App.PostsIndexController = Ember.ArrayController.extend({
actions: {
view: function(post){
this.transitionToRoute('post', post);
}
}
}
This way, when I cache a rendered copy of the page and serve that to an indexing bot, the bot will see a real link with an URL and follow it.
这样,当我缓存页面的呈现副本并将其提供给索引机器人时,机器人将看到一个带有 URL 的真实链接并跟随它。
(note also that transitionTo
is now deprecated in favour of transitionToRoute
)
(另请注意,transitionTo
现在不赞成使用transitionToRoute
)
回答by Myslik
None of these combinations will work in Ember.js, but you do not need to combine these two helpers. Why don't you just use action helper and let it bubble to controller or route? There you can use transitionToRoute
in controller or transitionTo
in route.
这些组合在 Ember.js 中都不起作用,但您不需要组合这两个助手。为什么不直接使用动作助手并让它冒泡到控制器或路由?在那里你可以transitionToRoute
在控制器或transitionTo
路由中使用。
For example in controller you could have code like this:
例如在控制器中你可以有这样的代码:
App.PostsController = Ember.ArrayController.extend({
clear: function () {
// implement your action here
this.transitionToRoute('index');
}
});
回答by neverfox
This works fine in 1.6.0-beta.5:
这在 1.6.0-beta.5 中工作正常:
<span {{action "someAction"}}>
{{#link-to "some.route"}}
Click Me
{{/link-to}}
</span>
The link will happen and then the click will bubble up to the action handler. It's documented (albeit indirectly) here.
链接将发生,然后点击将冒泡到动作处理程序。它记录在案(尽管是间接的)here。
Edit: corrected syntax in opening link tag
编辑:更正打开链接标签中的语法
回答by bargar
I like Cereal Killer's approach for its simplicity, but unfortunately it exhibits a problem for me. When the browser navigates to another route, it restarts the Ember application.
我喜欢 Cereal Killer 的方法,因为它很简单,但不幸的是,它给我带来了一个问题。当浏览器导航到另一个路由时,它会重新启动 Ember 应用程序。
As of Ember 2.6, the following simple approach does the trick:
从 Ember 2.6 开始,以下简单的方法可以解决问题:
<span {{action 'closeNavigationMenu'}}>
{{#link-to 'home' preventDefault=false}}
Go Home
{{/link-to}}
</span>
<span {{action 'closeNavigationMenu'}}>
{{#link-to 'home' preventDefault=false}}
Go Home
{{/link-to}}
</span>
This achieves the following:
这实现了以下目标:
- navigates to route 'home'
- action 'closeNavigationMenu' is invoked
- on mouseover, browser displays link that will be followed (for SEO and better UX)
- browser navigation does not result in reboot of Ember app
- 导航到路线“家”
- 调用“closeNavigationMenu”操作
- 在鼠标悬停时,浏览器显示将遵循的链接(用于 SEO 和更好的 UX)
- 浏览器导航不会导致 Ember 应用程序重启
回答by Cereal Killer
Having the same problem, i found this simple solution:
遇到同样的问题,我找到了这个简单的解决方案:
{{#linkTo eng.rent class="external-button"}}<div class="internal-button" {{action "updateLangPath"}} >X</div>{{/linkTo}}
then, managing the css classes external-button and internal-button in the stylesheet, i made sure that the "internal-button" was covering the whole "external-button" area; in this way it is not possible to click on the external-button without clicking on the internal-button.
然后,管理样式表中的 css 类 external-button 和 internal-button,我确保“internal-button”覆盖整个“external-button”区域;这样就不可能在不点击内部按钮的情况下点击外部按钮。
It works well for me; hope it can help...
这对我来说很有效; 希望它可以帮助...
回答by jdcravens
This is how I solved this in our demo application for the O'Reilly Ember.js book: https://github.com/emberjsbook.
这就是我在 O'Reilly Ember.js 书的演示应用程序中解决这个问题的方法:https: //github.com/emberjsbook。
You can see the complete source here: https://github.com/emberjsbook/rocknrollcall
你可以在这里看到完整的源代码:https: //github.com/emberjsbook/rocknrollcall
In the view:
在视图中:
{{#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}}
And the controller:
和控制器:
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: []
});
回答by pvans
Ember's link-to tags use routes to open new views, so you can perform whatever functionality you wanted to put in the link's 'action' attribute in the setupController
method of the target route instead of in a controller action.
Ember 的链接标签使用路由来打开新的视图,所以你可以执行你想要setupController
在目标路由的方法中而不是控制器操作中放置在链接的“动作”属性中的任何功能。
See here in the Ember guide: http://emberjs.com/guides/routing/setting-up-a-controller/
在 Ember 指南中查看此处:http: //emberjs.com/guides/routing/setting-up-a-controller/
This only works if you want to perform the action every time the route is accessed, however, as opposed to with specific links.
但是,这仅适用于您希望每次访问路由时都执行该操作的情况,而不是使用特定链接。
Make sure to include the controller.set('model', model);
line along with whatever else you put in there.
确保包括该controller.set('model', model);
行以及您放入的任何其他内容。