【问题标题】:Ember action helperEmber 动作助手
【发布时间】:2015-07-29 14:25:15
【问题描述】:

我的 ember 应用程序中的操作助手有问题。我在一个 UL 清单中有一份 LI 项目清单。列表可以有各种数量的项目。项目应在鼠标悬停时响应。第一个解决方案是在列表中的每个项目 (LI) 上添加鼠标输入操作,例如:

<ul>
 {{#each data key="id" as |item|}}
   <li {{action "mouseOverLi" on="mouseEnter"}}>  {{item.description}}</li>
{{/each}}
</ul>

此解决方案有效,但现在对于每个 LI 标签我都有一个操作,这不是一个好的解决方案。那么有没有其他解决方案。最好的办法是在 UL 标签中添加动作助手,并在 LI 子标签上添加过滤器。

换句话说,如何在 Ember 的操作助手中转换这个 jQuery 代码 sn-p:

$("ul").on("mouseover","li",function(){
    // some code.
});

【问题讨论】:

  • “这不是一个好的解决方案。”为什么?您的代码是否存在性能问题?过早的优化是万恶之源。

标签: ember.js


【解决方案1】:

为每个元素绑定一个动作是一个完美的解决方案,也是在 Ember 中处理它的标准方法:

<ul>
   {{#each data key="id" as |item|}}
     <li {{action "mouseOverLi" on="mouseEnter"}}>
       {{item.description}}
     </li>
   {{/each}}
</ul>

它还为您提供了能够传递 ember 对象而不是传递 DOM 节点的额外好处。例如:

<ul>
   {{#each data key="id" as |item|}}
     <li {{action "mouseOverLi" on="mouseEnter" item}}>
       {{item.description}}
     </li>
   {{/each}}
</ul>

然后无论你处理什么:

mouseOverLi: function(item){
  item.set("description", "Changed to something different!");
}

我怀疑您的反对意见是我们附加了很多事件处理程序,但这是一个老问题,除非您确实有大量奇怪的列表项,否则不应该成为问题。在这种情况下,您的性​​能问题首先是您有那么多列表项。

就性能而言,jQuery 实际上并没有对mouseenter 做出反应,它根本不能,因为mouseenter 只在ul 上触发一次,而不是在跨子元素移动时触发。那么https://jsfiddle.net/c8hk6ydn/ 是如何工作的呢?在 jQuery 中,mouseenter 是来自mouseover 的合成事件,请参阅:https://github.com/jquery/jquery/blob/2792845534e36c39dbb9c8369ed96aaefa560081/src/event.js#L779

所以现在,如果你坚持必须拥有,那么你基本上会像在其他情况下一样使用 jQuery。因为无论如何我们都在做一些非标准的事情:

App.HoverListComponent = Ember.Component.extend({
  tagName: "ul",
  didInsertElement: function(){
    this.$().on("mouseenter", "li", function(){
      console.log("Whatever you want to do");
    });
  }
});

然后在模板中:

{{#hover-list}}
  {{#each data key="id" as |item|}}
    <li>
      {{item.description}}
    </li>
  {{/each}}
{{/hover-list}}

JSBin: http://emberjs.jsbin.com/xiwoqubumo/5/edit?html,css,js,output 或者你可以尝试更原生的 ember-like 并使用 mouseOver 处理它:

App.HoverListComponent = Ember.Component.extend({
  tagName: "ul",
  mouseMove: function(e){
    // @todo Find the closest 'li' if the LI has 
    // other elements in it.
    // @todo Only fire once per element.
    if(e.toElement.tagName !== 'LI'){
      return;
    }
    $(e.toElement).css("color", "red");
  }
});

但基本上我的观点是,在做 Ember.js 时使用 Ember.js 的方式,不要像 jQuery 那样做,否则你会得到非常尴尬的代码。

【讨论】:

  • 感谢您的回复。这只是一个示例,因为我发现自己很多次都需要动作助手中的“过滤器”参数来加快在动作处理函数中的编写速度。我已经用“didInsertElement”函数完成了它,我只是想也许有更好的解决方案。现在我很清楚我没有做错什么。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
相关资源
最近更新 更多