【问题标题】:Combine linkTo and action helpers in Ember.js在 Ember.js 中结合 linkTo 和 action 助手
【发布时间】: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:&lt;span {{action 'yourAction'}}&gt; {{link-to 'yourRoute'}} link text {{/link-to}} &lt;/span&gt;
  • 这将是 2 个 HTML 元素而不是 1 个。此外,您需要在 CSS 中进行更改。如果有可能在 1 个元素中做到这一点并且 seo 还可以,那么为什么不去做呢? ;)和1件更多的东西。如果你有几十个或几百个这样的链接怎么办。那将是您需要的 HTML 样板的两倍。
  • 好吧,我只是不介意 2 个 html 元素呵呵

标签: javascript ember.js handlebars.js htmlbars ember-components


【解决方案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 无用,搜索引擎机器人什么也看不到。

      如果您希望将链接指向的内容编入索引,最简单的方法是在其中放置一个很好的旧&lt;a href=x&gt;。最好使用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 的这个时代,您可以注入路由器服务并转换,而不必冒泡到顶部
            猜你喜欢
            • 2013-02-12
            • 1970-01-01
            • 2013-06-27
            • 1970-01-01
            • 2013-08-15
            • 1970-01-01
            • 2013-01-05
            • 2022-11-29
            • 1970-01-01
            相关资源
            最近更新 更多