Выход в компоненте, который вызывается из каждого помощника
Это часть моего шаблона компонента:
{{#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}}
Я хочу, чтобы пользователь мог настроить html, который используется для отображения результатов.
Проблема заключается в том, что {{yield}} вызывается while в помощнике {{#each}}, и если компонент объявлен следующим образом:
{{#auto-suggest source=controller.employees destination=controller.chosenEmployees}}
<span class=\"result-name\"><img src="img/small_avatar.png"/>{{fullName}}</span>
{{/auto-suggest}}
Тогда блок между {{# auto-suggest}} не имеет контекста помощника {{#each}} в компоненте.
Есть ли что-нибудь, что я могу сделать, или это так, как есть?
Ответы
Ответ 1
UPDATE
Теперь, когда Простой живой пример
Конечно, вы можете получить любые переменные, используя {{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}}
ДЛЯ СТАРЫХ ВЕРСИЙ
Вы можете переопределить метод _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() }
});
}
}
});
Ответ 2
На основе ответа Marcio Junior вы можете увеличить _yield
без повторного создания всей функции. Хотя вместо прозрачного изменения поведения _yield
я бы рекомендовал добавить параметр к вашему компоненту. Например.
{{#whatever-component useComponentContext=true}}
И в вашем файле JavaScript компонента:
// duck-punch _yield to use the current view
_yield: function(content, options) {
var oldParentView = this._parentView;
if (this.get('useComponentContext')) {
// temporarily set _parentView to the view we want
this.set('_parentView', options.data.view);
// expose the original context via `_parent`
options.data.view.get('context').set('_parent', oldParentView.get('context'));
}
// call the built-in _yield like normal
var result = this._super.apply(this, arguments);
// restore _parentView
this.set('_parentView', oldParentView);
return result;
}
С этим что-то вроде
{{!-- whatever-component.hbs --}}
{{#each something in somethings}}
<div {{bind-attr title=something.id}}>
{{#with something}}
{{yield}}
{{/with}}
</div>
{{/each}}
{{!-- some-view.hbs --}}
{{#whatever-component.hbs}}
<h1>{{id}}</h1>
<p>{{someField}}</p>
<div>{{_parent.theContextTheComponentIsBeingRenderedIn}}</div>
{{/whatever-component.hbs}}
будет работать как ожидалось