【问题标题】:Call method from other template after rendering渲染后从其他模板调用方法
【发布时间】:2017-09-26 13:21:27
【问题描述】:

使用 Meteor,我得到了一个模板,其中包含 2 个其他模板 A 和 B。 A 有一个<select> 标签,B 有一个<canvas>,根据模板 A 的选择,将在其上绘制一些东西。

When the selection changes, A should call someMethod` of B, and this method should get some data from the db and then draw the canvas.我怎样才能实现这种行为?

简单地使用Template.B.someMethod = function (bla) ...,然后在A 的JS 中调用Template.B.someMethod(hi) 会导致错误,因为someMethod 访问B 的DOM canvas 元素,当A 在加载时第一次更改时该元素不会呈现。

调用该方法的合适方式是什么?还是应该将这两个模板合并在一起?

【问题讨论】:

    标签: templates meteor


    【解决方案1】:

    无需组合 A 和 B 模板。这里父级的目的是协调 A 和 B 之间的数据更改。也就是说,您不会在 B 上调用函数,而是给它所需的数据以便它可以响应。

    P(父级)可以将 A 在其数据通过 select 更改时调用的函数推入 A。然后,P 可以通过 Meteor 的正常反应将该数据推送到 B。然后 B 可以响应该更改。

    例如

    <template name="P">
        {{A changeHandler=getChangeHandler}}
        {{B selection=selectedData}}
    </template>
    

    P.js:

    Template.P.onCreated(function() {
        this.data = new ReactiveVar();
    });
    
    Template.P.helpers({
        getChangeHandler() {
            let template = Template.instance();
    
            return function(data) {
                template.data.set(data);
            }
        },
    
        selectedData() {
            return Template.instance().data.get();
        }
    });
    

    A.js:

    Template.A.onCreated({
        this.changeHandler = new ReactiveVar(Template.currentData().changeHandler); // i think this is right
    });
    

    以及每当 A 数据发生变化时:

    let changeHandlerFn = template.changeHandler.get();
    
    if (_.isFunction(changeHandlerFn)) {
        changeHandlerFn(updatedData);
    }
    

    【讨论】:

    【解决方案2】:

    除了@zim 的回答,您还可以使用https://stackoverflow.com/a/43687311/5108796 的变体:

    HTML(实际上是空格键)

    <template name="Parent">
        {{> Child1 sharedVar1=sharedVar}}
        {{> Child2 sharedVar2=sharedVar}}
    </template>
    

    JavaScript

    import { ReactiveVar } from 'meteor/reactive-var';
    
    // Just initialize the variable. Could also be within the scope of a template.
    var myReactiveVar = new ReactiveVar();
    
    Template.Parent.helpers({
        // This is what will be sent to Child1 and Child2.
        sharedVar: function () {
            return myReactiveVar;
        }
    });
    
    Template.Child1.events({
        'change select': function (event, template) {
            // This will trigger a re-execution of Child2 autorun.
            template.data.sharedVar1.set(myNewValue);
        }
    });
    
    Template.Child2.onCreated(function () {
        var sharedVar2 = this.data.sharedVar2;
    
        this.autorun(function () {
            // As usual, this is reactive.
            var newValue = sharedVar2.get();
    
            // Perform some operation using newValue…
        });
    });
    

    (当然你可以将这些拆分成几个JS文件)

    【讨论】:

    • 谢谢!我绝对更喜欢你的答案,因为它比@zim 更简单,但也感谢你!会尽快尝试的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多