Meteor 如何为模板项指定客户端布尔标志?

Meteor 如何为模板项指定客户端布尔标志?,meteor,handlebars.js,Meteor,Handlebars.js,我正在使用meteor的Todo示例来了解它是如何工作的,我正在尝试为Todo项目添加一个描述,当您单击它时,它会显示在标题下方。“当你点击它的时候”这部分正是我遇到的问题。我试图弄清楚如何向每个Todo项目客户端添加一个布尔“查看”变量,而不反映该服务器端。显然,当一个用户查看一个项目时,并不是每个用户都希望查看该项目。我得到了一个基本的实现,添加了一个仅限客户端的集合,该集合只是正在查看的Todo ID的列表,然后使用此代码作为模板,以了解是否正在查看某个想法: Template.todo_

我正在使用meteor的Todo示例来了解它是如何工作的,我正在尝试为Todo项目添加一个描述,当您单击它时,它会显示在标题下方。“当你点击它的时候”这部分正是我遇到的问题。我试图弄清楚如何向每个Todo项目客户端添加一个布尔“查看”变量,而不反映该服务器端。显然,当一个用户查看一个项目时,并不是每个用户都希望查看该项目。我得到了一个基本的实现,添加了一个仅限客户端的集合,该集合只是正在查看的Todo ID的列表,然后使用此代码作为模板,以了解是否正在查看某个想法:

Template.todo_item.viewing = function () {
    return Viewing_Todos.find({title: this.title}).count() > 0;
};
但这并不是一个理想的解决方案。正如我所说的,我希望在每个todo项目上都有一个客户端布尔变量来表示是否正在查看它

我尝试将其更改为:

Template.todo\u item.view=false

然后我的点击事件是:

'click .todo-description': function(event) {
   event.target.viewing = !event.target.viewing;
}
我在控制台日志输出中添加了查看“event.target.viewing”是什么,它似乎正在正确更新,但Handlebar不再动态更新DOM,以反映项目处于“查看”状态

车把HTML是:

      {{#if viewing}}<br/>
      <div class="todo-description">
          {{text}}
      </div>
      {{/if}}
但这似乎根本不起作用


谢谢你的帮助!一般来说,我对web开发相当陌生,但到目前为止我喜欢Meteor。

您应该使用如下会话变量:

Template.todo_item.created=function(){
    Session.set(this.data._id+"-viewing",false);
};

Template.todo_item.helpers({
    viewing:function(){
        return Session.get(this._id+"-viewing");
    }
});

Template.todo_item.events({
    "click .todo-description":function(event,template){
        var viewing=Session.get("-viewing");
        Session.set(template.data._id+"-viewing",!viewing);
    }
});
此代码假定todo_项模板数据上下文是一个具有自己唯一id的有效Todos文档

我们使用这个_id来命名一个唯一的会话变量,该变量将反应性地存储项目的当前查看状态,无论何时修改该变量,模板都将重新加载

注意我们如何以不同的方式访问数据上下文:

  • 在创建/呈现/销毁的回调中,“this”绑定到模板实例,我们可以使用data属性(this.data)访问数据上下文

  • 在模板帮助程序中,“this”直接绑定到数据上下文

  • 在事件处理程序中,模板实例可以通过参数访问,因此我们可以再次使用数据属性(template.data.\u id)


在Meteor的未来版本中,模板将有自己的作用域会话变量,希望这种技术将更容易实现。

完全不需要单独的客户端数据库。通常,如果您想要控制UI状态,“查看”是一个完美的例子,那么您可以设置一个变量。代码可能如下所示:

// Click event
'click .todo-description': function (event, templ) {
    Session.set('viewing-todo', templ._id); // We're now viewing todo with id=_id
}

// Are they viewing a todo?
if (Session.get('viewing-todo')) // ...

// Or perhaps they're viewing "foobla" todo?
if (Session.equals('viewing-todo', 'fooblaId')) // ...
// Click event
'click .todo-description': function (event, templ) {
    $(event.target).data('viewing', true);
}

// Are they viewing a todo?
if ($('#todoElement').data('viewing')) //...
但是,如果您想为每个todo项目单独设置一个“查看”标志(他们一次可以查看多个项目吗?),可以尝试为每个todo元素附加一个。这是一个简单的操作。您的代码可能如下所示:

// Click event
'click .todo-description': function (event, templ) {
    Session.set('viewing-todo', templ._id); // We're now viewing todo with id=_id
}

// Are they viewing a todo?
if (Session.get('viewing-todo')) // ...

// Or perhaps they're viewing "foobla" todo?
if (Session.equals('viewing-todo', 'fooblaId')) // ...
// Click event
'click .todo-description': function (event, templ) {
    $(event.target).data('viewing', true);
}

// Are they viewing a todo?
if ($('#todoElement').data('viewing')) //...

谢谢我确实希望用户能够一次查看多个Todo,这就是为什么我避开会话变量方法的原因。我不知道jQuery的数据方法。再次感谢!我对“他们正在观看”部分有意见。。我正在尝试编写Template.think\u item.viewing,但在该范围内,“this”指的是数据对象。。如何获取与该数据对象关联的DOM对象?@JDiPierro您是否试图在模板帮助程序、单击事件或渲染方法中使用
this
?模板帮助程序。“this”返回的是实际的Todo对象,而不是DOM对象。即将推出的Meteor UI将使此操作更简单,但一种方法是为每个Todo元素提供一个与Todo的_id对应的id属性,或者添加一个数据id属性。然而,如果你想这样做,通常会有更好的方法。