Meteor:是否有每个模板的反应式作用域? [英] Meteor: Is there a reactive per-template scope?

查看:13
本文介绍了Meteor:是否有每个模板的反应式作用域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在同一页面上的多个(任意多个)位置呈现相同的 Handlebars 模板.在每个模板中,我想要一个按钮来切换 div 的可见性.当我使用 Session.set 保存此状态时,单击一个按钮显然会切换所有模板实例中的所有 div,这是不需要的.

I'm rendering the same Handlebars template in multiple (arbitrarily many) locations on the same page. Inside each template, I want a button to toggle the visibility of a div. When I save this state with Session.set, clicking one button obviously toggles all the divs in all the template instantiations which is not desired.

我可以将状态保存在模板实例的数据上下文中(它绑定到 Template.myTemplate.renderedTemplate 中的 this.data.myTemplate.created 回调),但有两个问题.

I could save the state in the data context of the template instance (which is bound to this.data in the Template.myTemplate.rendered and Template.myTemplate.created callbacks), but there are two problems with that.

  1. this.data 不是响应式数据源,因此不会传播到 div
  2. 我无权访问 Template.myTemplate.events 中的模板实例(如 meteor-core)
  1. this.data isn't a reactive data source, so will not propagate to the div
  2. I don't have access to the template instance in Template.myTemplate.events (as discussed on meteor-core)

最后,我可以以某种方式将它保存到一个集合中.但是我将如何唯一标识每个渲染模板的状态?jQuery 可能也有一种hacky 方式,但这不是我想要开发应该与反应式模板一起使用的 Meteor 应用程序的方式.尤其是当模板变得更加复杂时.

Finally, I could somehow save it to a collection. But how would I uniquely identify the state for each template rendered? There might also be a hacky way with jQuery, but that's not the way I want to develop Meteor apps that are supposed to work with reactive templates. Especially, when that template gets more complex.

我是不是遗漏了什么,或者真的没有相当于 AngularJS 的控制器,每个模板实例化都传递一个 $scope ?

Am I missing something or is there really no equivalent to AngularJS's controllers that get passed a $scope for each template instantiation?

更新:我在想这样的事情.

template.html:

template.html:

<template name="jsonObject">
    <input type="button" />
    <div class="{{hidden}}">content</div>
</template>

client.js:

Template.jsonObject.hidden = function(){
    var ret = "";
    if (this._hidden) {
        ret = "hidden";
    }
    return ret;
};

Template.jsonObject.events({
    'click input' : function(event, template){
        template.data._hidden = true;
    }
});

推荐答案

所有其他答案都太复杂和/或过时了.从 Meteor 1.0 开始,维持每个模板状态的推荐解决方案是使用 反应变量存储在模板实例中:

All other answers are too complicated and/or outdated. As of Meteor 1.0, the recommended solution to maintaining per-template state is to use reactive variables stored in the template instance:

模板实例对象表示文档中模板的出现.它可用于访问 DOM,并且可以为其分配属性,这些属性在模板被动更新时会持续存在.[...] 您可以为对象分配您选择的其他属性.

A template instance object represents an occurrence of a template in the document. It can be used to access the DOM and it can be assigned properties that persist as the template is reactively updated. [...] you can assign additional properties of your choice to the object.

反应变量由 reactive-var 核心包提供:

Reactive variables are provided by the reactive-var core package:

ReactiveVar 持有一个可以获取和设置的单一值,因此根据响应数据的通常约定,调用 set 将使任何调用 get 的计算无效来源.

A ReactiveVar holds a single value that can be get and set, such that calling set will invalidate any Computations that called get, according to the usual contract for reactive data sources.

您的代码变为:

Template.jsonObject.onCreated = function () {
  this.hidden = new ReactiveVar(false);
};

Template.jsonObject.helpers({
  hidden: function () {
    return Template.instance().hidden.get() ? 'hidden' : '';
  }
});

Template.jsonObject.events({
  'click input': function (event, template) {
    template.hidden.set(true);
  }
});

HTML 与您期望的相同:

The HTML is the same as you'd expect:

<template name="jsonObject">
  <button>Click Me</button>
  <p>Hidden is {{hidden}}.</p>
</template>

这篇关于Meteor:是否有每个模板的反应式作用域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆