流星,从父模板调用儿童模板中的功能

时间:2014-12-01 13:25:13

标签: meteor meteor-blaze

如果我的父模板Container带有子模板Content avec只有一个按钮:

<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();
    }
} );

但有时候,我需要以另一种方式实现它。父母在他的孩子中调用一个函数。你的做法是什么?


编辑:

我将它保存在meteorpad中以显示它的实际效果并使其易于分叉:http://meteorpad.com/pad/48NvCFExxW5roB34N/test-pass-callback-to-parent

4 个答案:

答案 0 :(得分: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>

答案 1 :(得分:1)

根据我对Meteor的经验,它似乎更倾向于使用事件驱动的UI设计。这意味着您不会直接直接调用父方法或子方法,但您可以触发自定义事件或设置Session变量。所以你可以这样做:

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对象是被动的,因此只要设置了'button.lastClickTime'会话值,就会调用回调方法。

然后你可以反转set / get调用来通知父级的孩子。

答案 2 :(得分: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.
    }
} );

*)假设父模板中没有其他按钮。如果是这样,请为按钮创建一个唯一的名称,以便您可以从父级中唯一地选择它。

答案 3 :(得分:0)

您还可以在子级中创建模板函数,然后在创建子级时在父级上设置模板函数。这需要使用meteor-template-extension软件包。虽然如果您深入研究该软件包,则可以只提取执行parent()函数的代码。

Template.child.onCreated(function() {
   let instance = this;
   instance.someFunction = function() {...};
   instance.parent(1, false).someFunction = instance.someFunction;
});

然后,父级可以在事件处理程序(或任何地方)中调用它。