从每个帮助程序调用的组件中的yield

dag*_*da1 10 javascript ember.js

这是我组件模板的一部分:

{{#each displayResults}}
  <li {{action addSelection this}} {{bindAttr class=\":result active\"}}>
  {{#if controller.template}}
    {{yield}}
  {{else}}
    <span class=\"result-name\">{{displayHelper controller.searchPath}}</span>
  {{/if}}
  <\/li>
{{/each}}
Run Code Online (Sandbox Code Playgroud)

我希望用户能够自定义用于显示结果的html.

问题是在{{#each}}帮助器中调用{{yield}},如果组件声明如下:

{{#auto-suggest source=controller.employees destination=controller.chosenEmployees}}
<span class=\"result-name\"><img src="img/small_avatar.png"/>{{fullName}}</span>
{{/auto-suggest}}
Run Code Online (Sandbox Code Playgroud)

然后{{#auto-sugges}}之间的块没有组件中{{#each}}帮助器的上下文.

有什么我可以做的或者这就是它的方式吗?

Mar*_*ior 18

UPDATE

现在ember 1.10已经登陆,引入了一种称为块参数的新语法.所以不需要覆盖该_yield方法.例如,在组件模板内部,您可以:

<ul>    
  {{#each item in source}}
    <li>
    {{! the component is being used in the block form, so we yield}}
    {{#if template.blockParams}}
      {{yield item}}
    {{! no block so just display the item}}
    {{else}}
      {{item}}
    {{/if}}
    </li>
  {{/each}}
</ul>
Run Code Online (Sandbox Code Playgroud)

然后在使用组件时,您将获得传递给{{yield}}使用的参数as |var|

{{! no block, the component will just display the item}}
{{auto-suggest source=model as |item|}}

{{! in the block form our custom html will be used for each item}}
{{#auto-suggest source=model as |item|}}
  <h1>{{item}}</h1>
{{/auto-suggest}}
Run Code Online (Sandbox Code Playgroud)

简单的实例

当然,您可以使用{{yield name age occupation hobbies}}以下组件生成任何变量并在组件中捕获它们:

{{#x-foo user=model as |name age occupation hobbies|}}
  Hi my name is {{name}}, I am {{age}} years old. Major of the times I am {{occupation}}, but also love to {{hobbies}}.
{{/x-foo}}
Run Code Online (Sandbox Code Playgroud)

适用于旧版本

您可以覆盖默认_yield方法,和Ember.Component,并更改context: get(parentView, 'context')context: get(view, 'context').

App.AutoSuggestComponent = Ember.Component.extend({
  _yield: function(context, options) {      
    var get = Ember.get, 
    view = options.data.view,
    parentView = this._parentView,
    template = get(this, 'template');

    if (template) {
      Ember.assert("A Component must have a parent view in order to yield.", parentView);      
      view.appendChild(Ember.View, {
        isVirtual: true,
        tagName: '',
        _contextView: parentView,
        template: template,
        context: get(view, 'context'), // the default is get(parentView, 'context'),
        controller: get(parentView, 'controller'),
        templateData: { keywords: parentView.cloneKeywords() }
      });
    }
  }
});
Run Code Online (Sandbox Code Playgroud)