2014-12-01 3 views
9

Если у меня есть родительский шаблон Container с шаблоном ребенка Content АВЭК только кнопка:Метеор, вызов функции в шаблоне ребенка из родительского шаблона

<head> 
    <title>test</title> 
</head> 

<body> 
    {{> Container}} 
</body> 

<template name="Container"> 
    {{# Content callback = callBack }} 
     <button>ok</button> 
    {{/Content}} 
</template> 

<template name="Content"> 
    {{> UI.contentBlock}} 
</template> 

Если можно передать функцию в callback. Например:

Template.Container.helpers({ 
    callBack: function() { 
     return function() { 
      console.log('this is my callback'); 
     } 
    } 
}); 

Так что в моем шаблоне контента я могу вызвать функцию из родительского шаблона. Например, это:

Template.Content.events({ 
    'click button': function (e, tmpl) { 
     tmpl.data.callback(); 
    } 
}); 

Но иногда мне нужно, чтобы это произошло по-другому. Родитель, вызывающий функцию в своем дочернем элементе. Каков ваш способ сделать это?


EDIT:

Я сохранил его в meteorpad, чтобы показать его в действии и сделать его легко вилке: http://meteorpad.com/pad/48NvCFExxW5roB34N/test-pass-callback-to-parent

ответ

16

Вот образец, который вы могли бы использовать. Определите класс Child и шаблон child; идея заключается в том, что внутри шаблона child контекст данных представляет собой экземпляр Child. Например, я создам компонент, у которого есть число, которое можно увеличить, нажав кнопку.

<template name="child"> 
    <button class="increment">{{number.get}}</button> 
</template> 
function Child() { 
    this.number = new ReactiveVar(0); 
} 

Template.child.events({ 
    "click .increment": function() { 
    this.number.set(this.number.get() + 1); 
    } 
}); 

В created обратного вызова родителей, создать Child экземпляр и сохранить его на экземпляре шаблона.Тогда в родительском шаблоне, взывать к child, проходя в Child в качестве контекста данных:

Template.parent.created = function() { 
    this.childInstance = new Child(); 
} 

Template.parent.helpers({ 
    childInstance: function() { 
    return Template.instance().childInstance; 
    } 
}); 
<template name="parent"> 
    {{> child childInstance}} 
</template> 

Теперь вы можете определить методы на Child прототипа и вызывать их из родительского шаблона, например:

Child.prototype.getNumberTimesTwo = function() { 
    return this.number.get() * 2; 
} 
<template name="parent"> 
    {{> child childInstance}} 
    That number multiplied by two is: {{childInstance.getNumberTimesTwo}} 
</template> 
+0

Я использовал [event emitter] (https://github.com/Olical/EventEmitter) для связи между шаблонами раньше, вы передаете событие-эмиттер в дочерний шаблон, как указано выше, он работает достаточно хорошо. Детский шаблон также может генерировать события, которые должны быть получены родительским шаблоном. – nephets

1

Основываясь на моем опыте с Метеор, кажется, что это способствует более дизайна пользовательского интерфейса, управляемого событиями. Это означает, что вы прямо не вызывали бы родительский или дочерний методы напрямую, но вы могли бы запустить настраиваемое событие или установить переменную сеанса. Таким образом, вы могли бы сделать что-то вроде:

Template.Container.helpers({ 
    callBack: function() { 
     Session.get('button.lastClickTime'); 
     console.log('this is my callback'); 
    } 
}); 
Template.Content.events({ 
    'click button': function (e, tmpl) { 
     Session.set('buttom.lastClickTime', new Date()); 
    } 
}); 

Объект Session является реактивным поэтому метод обратного вызова будет вызываться в любое время, что значение Session «button.lastClickTime» установлено.

Тогда вы можете просто отменить вызов set/get, чтобы уведомить ребенка из родителя.

1

Вы можете зарегистрировать обработчик событий на родительский шаблон, который инициирует события в шаблоне ребенка с помощью селектора, который соответствует элементам в шаблоне ребенка, как это:

Template.Container.events({ // 'Container' is the parent template 
    'click button': function (e, tmpl) { // Selector for an element in the child-template* 
     // You will now have access to the parent's context instead of the child's here. 
    } 
}); 

*) Предполагая, что есть нет другие кнопки в родительском шаблоне. Если да, сделайте уникальное имя для кнопки, чтобы вы могли однозначно выбрать ее из родителя.

+0

Это может работать в другом случае. Но у меня «Контент» является компонентом и будет появляться несколько раз в родительском шаблоне. И целью является доступ к дочернему контексту от родителя, а не к доступу к родительскому элементу из дочернего элемента. – fabien