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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 03:21:43  来源:igfitidea点击:

Combine linkTo and action helpers in Ember.js

javascriptember.jshandlebars.jshtmlbarsember-components

提问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.

检查我对Ember 2.0 兼容的回答,对于 SEO 解决方案还可以

采纳答案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 invokeActionparam 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-toat all but instead using an actionand then transitionToRoute) is that it's useless for SEO, search engine bots will see nothing.

Myslik 的答案(根本不使用link-to,而是使用actionand 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-toso 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-toto 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 transitionTois 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 transitionToRoutein controller or transitionToin 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 setupControllermethod 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);行以及您放入的任何其他内容。