在Ember.js中组合linkTo和动作助手

Dan*_*mak 30 javascript handlebars.js ember.js ember-components htmlbars

我需要在Ember.js中组合linkTo和action helpers.我的代码是:

{{#link-to 'index'}}<span {{action 'clear'}}>Clear</span>{{/link-to}}
Run Code Online (Sandbox Code Playgroud)

但我想这样做:

{{#link-to 'index' {{action 'clear'}} }}Clear{{/link-to}}
Run Code Online (Sandbox Code Playgroud)

并且:

<li>
    {{#link-to 'support'}}
        <span {{action 'myAction' 'support'}}>Support</span>
    {{/link-to}}
</li>
Run Code Online (Sandbox Code Playgroud)

至:

<li>
    {{#link-to 'support' {{action 'myAction' 'support'}} }}Support{{/link-to}}
</li>
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

检查我对Ember 2.0兼容的答案,确定SEO解决方案.

Dan*_*mak 29

Ember Link Action插件

我最近开发了这个插件来解决这个问题与Ember 2.0 - 2.14+兼容(1.13也有效!)风格并利用关闭动作/动作名称.这对SEO来说还可以!

安装插件

ember install ember-link-action
Run Code Online (Sandbox Code Playgroud)

用法

您可以将关闭操作作为invokeActionparam 传递给{{link-to}}组件:

{{#link-to 'other-route' invokeAction=(action 'testAction')}}
  Link to another route
{{/link-to}}
Run Code Online (Sandbox Code Playgroud)

您还可以使用操作名称而不是关闭操作:

{{#link-to 'other-route' invokeAction=(action 'testAction' param1 param2)}}
  Link to another route
{{/link-to}}
Run Code Online (Sandbox Code Playgroud)

要将参数传递给操作,您可以使用:

ember install ember-link-action
Run Code Online (Sandbox Code Playgroud)

兼容性

自动测试套件确认插件可以使用1.13到最新的Ember 3版本.

它适用于Ember的发行版,测试版和金丝雀版.

Addon GitHub存储库.欢迎捐款.


Nol*_*and 18

更新:请参阅下面的Michael Lang对Ember 1.8.1+的评论

Myslik的答案(完全没有使用link-to,而是使用一个action然后transitionToRoute)的问题是它对SEO没用,搜索引擎机器人什么都看不到.

如果你想要链接所指向的内容被索引,那么<a href=x>在那里拥有一个好老的最容易.最好使用,link-to以便您的链接网址与您的路线网址保持同步.我使用的解决方案既提供了执行工作的操作,也提供了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);
  }
});
Run Code Online (Sandbox Code Playgroud)

然后我可以指定要采取的操作以及在Handlebars中传递操作的内容:

<span {{action 'view' this}}>
  {{#link-to 'post' action='view' actionParam=this}}
    Post Title: {{title}}
  {{/link-to}}
</span>
Run Code Online (Sandbox Code Playgroud)

在控制器中:

App.PostsIndexController = Ember.ArrayController.extend({
  actions: {
    view: function(post){
      this.transitionToRoute('post', post);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这样,当我缓存页面的呈现副本并将其提供给索引机器人时,机器人将看到与URL的真实链接并遵循它.

(另请注意,transitionTo现在已弃用赞成transitionToRoute)

  • 谢谢你的回答!看来,链接帮助器的设计可能已经发生了变化.在Ember 1.8.1中,我不得不替换this.get('controller').send(action,this.get('actionParam')); with this.sendAction('action',this.get('actionParam')); 为了让动作传播到我的路线的控制器. (2认同)

小智 17

这些组合都不适用于Ember.js,但您不需要将这两个帮助器组合在一起.为什么不直接使用动作助手并让它冒泡到控制器或路线?你可以transitionToRoute在控制器或transitionTo路线中使用.

例如在控制器中你可以有这样的代码:

App.PostsController = Ember.ArrayController.extend({
    clear: function () {
        // implement your action here
        this.transitionToRoute('index');
    }
});
Run Code Online (Sandbox Code Playgroud)


nev*_*fox 10

这在1.6.0-beta.5中运行良好:

<span {{action "someAction"}}>
  {{#link-to "some.route"}}
    Click Me
  {{/link-to}}
</span>
Run Code Online (Sandbox Code Playgroud)

链接将发生,然后点击将冒泡到动作处理程序.它在这里记录(尽管是间接的).

编辑:打开链接标记中的更正语法


bar*_*gar 6

我喜欢Cereal Killer的简洁方法,但遗憾的是它对我来说是一个问题.当浏览器导航到另一个路由时,它会重新启动Ember应用程序.

从Ember 2.6开始,以下简单方法就可以解决问题:

<span {{action 'closeNavigationMenu'}}> {{#link-to 'home' preventDefault=false}} Go Home {{/link-to}} </span>

这实现了以下目标:

  • 导航到"回家"路线
  • 动作'closeNavigationMenu'被调用
  • 在鼠标悬停时,浏览器显示将遵循的链接(用于SEO和更好的用户体验)
  • 浏览器导航不会导致重新启动Ember应用程序