2

我在使用流星中的保留方法时遇到问题。它似乎没有做我想做的事。

基本上,我有三个嵌套模板,它们在渲染时在关闭状态下看起来像这样:

<div class="Dropdown"><!--From Template1-->
    <div class="Group"><!--From Template2-->
        <div class="SubGroup"><!--From Template3-->
            I'm the subgroup's content!
        </div>
    </div>
</div>

要查看 .SubGroup 节点中的内容,所有模板包装器都需要带有 .Open 类名。这是在点击事件上完成的。这是打开状态下的样子:

<div class="Dropdown Open"><!--From Template1-->
    <div class="Group Open"><!--From Template2-->
        <div class="SubGroup Open"><!--From Template3-->
            I'm the subgroup's content!
        </div>
    </div>
</div>

问题是,当事件触发并从 .SubGroup 的内容中更改数据库时,看起来Template2 和 Template3 都被重新渲染并丢失了它们以编程方式应用的 .Open 类

我已经尝试Template.Template2.preserve(['.Group']); 在每个模板上使用我认为可能会影响它的几乎每个选择器。我也尝试过 {{#constant}} 和 {{#isolated}} 助手,但还没有得到预期的结果。

防止 Meteor 抹去我的班级名称的正确方法是什么?

4

1 回答 1

2

您应该使用 Session 变量和 Handlebars 助手。

<template name="dropdown">
    opened helper resolves to current dropdown state
    <div class="dropdown {{opened}}">
        iterate over each group using a cursor
        {{#each groups}}
            call subtemplate fed with current group document
            fetched from the cursor
            {{> group}}
        {{/each}}
    </div>
</template>

<template name="group">
    assign a unique id to the group div, using the document._id
    <div id="group-{{_id}}" class="group {{opened}}">
        ... and so on
    </div>
</template>

Template.dropdown.helpers({
    opened:function(){
        // Session variable will be undefined on first page view (closed state)
        // then it will have the value set in the click handler
        return Session.get("dropdown-opened")?"open":"";
    },
    groups:function(){
        return Groups.find();
    }
});

Template.dropdown.events({
    "click .dropdown":function(){
        var opened=Session.get("dropdown-opened");
        // toggle open state
        Session.set("dropdown-opened",!opened);
    }
});

// executed once on each template instance creation
Template.group.created=function(){
    // this.data._id is the fetched document._id
    // comment this line if you don't want your stuff to be collapsed
    // when the template is re-created (ie when you change page)
    Session.set("group-"+this.data._id+"-opened",false);
};

Template.group.helpers({
    opened:function(){
        // this._id is the fetched document._id
        return Session.get("group-"+this._id+"-opened")?"open":"";
    },
    subGroups:function(){...}
});

Template.group.events({
    "click .group":function(event,template){
        // once again, template.data._id corresponds to the id of the
        // document used to feed the group template
        var sessionKey="group-"+template.data._id+"-opened";
        var opened=Session.get(sessionKey);
        Session.set(sessionKey,!opened);
    }
});

这是未经测试的代码,但我在我的应用程序上做了类似的事情,它就像一个魅力。我认为这是实现此类事情的 Meteor 方式(Session+helpers)(而不是使用 jQuery 来操作 DOM 和类名)。不幸的是,这种模式非常冗长,对于来自非 Meteor 经典前端 JS web 应用程序开发的开发人员来说可能有点晦涩难懂,但我相信这会得到改进。

于 2013-08-23T16:10:24.690 回答