【问题标题】:How do I give a Template item a client-side boolean flag?如何为模板项提供客户端布尔标志?
【发布时间】:2013-11-04 04:53:20
【问题描述】:

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

Template.todo_item.viewing = function () {
    return Viewing_Todos.find({title: this.title}).count() > 0;
};

虽然这并不是一个理想的解决方案。正如我所说,我希望每个待办事项上都有一个客户端布尔变量来说明它是否正在被查看。

我试着把它改成这样:

Template.todo_item.viewing = false;

然后我的点击事件是:

'click .todo-description': function(event) {
   event.target.viewing = !event.target.viewing;
}

我在控制台日志输出中添加了“event.target.viewing”是什么,它似乎正在正确更新,但 Handlebars 不再动态更新 DOM 以反映该项目处于“查看”状态。

Handlebars HTML 是:

      {{#if viewing}}<br/>
      <div class="todo-description">
          {{text}}
      </div>
      {{/if}}

我认为我可能必须在助手中执行此操作,所以我尝试了以下操作:

Template.todo_item.helpers({
    viewing: false;
});

但这似乎也根本不起作用。

感谢您的帮助!总的来说,我对 Web 开发还很陌生,但到目前为止我很喜欢 Meteor。

【问题讨论】:

    标签: meteor handlebars.js


    【解决方案1】:

    为此,完全不需要单独的客户端数据库。一般来说,如果你想控制 UI 状态,“查看”就是一个很好的例子,你可以设置一个Meteor Session 变量。代码可能如下所示:

    // 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')) // ...
    

    但是,如果您想为每个待办事项设置一个单独的“查看”标志(他们一次可以查看多个吗?),您可以尝试将data-* attribute 附加到每个待办事项元素。使用jQuery data method 很容易做到这一点。您的代码可能如下所示:

    // Click event
    'click .todo-description': function (event, templ) {
        $(event.target).data('viewing', true);
    }
    
    // Are they viewing a todo?
    if ($('#todoElement').data('viewing')) //...
    

    【讨论】:

    • 谢谢!我确实希望用户一次能够查看多个 Todo,这就是我回避 Session 变量方法的原因。我不知道 jQuery 的数据方法。再次感谢!
    • 我在“他们正在查看”部分遇到问题。我正在尝试编写 Template.thought_item.viewing 但在该范围内“this”指的是数据对象。如何获取与该数据对象关联的 DOM 对象?
    • @JDiPierro 您是否尝试在模板助手或点击事件或渲染方法中使用this
    • 模板助手。 "this" 返回的是实际的 Todo 对象而不是 DOM 对象。
    • 即将推出的 Meteor UI 将使这更简单,但一种方法是为每个 todo 元素提供一个与 todo 的 _id 对应的 id 属性,或者添加一个 data-id 属性。但是,如果您尝试这样做,通常会有更好的方法。
    【解决方案2】:

    你应该像这样使用 Session 变量:

    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_item 模板数据上下文是一个有效的 Todos 文档,具有自己的唯一 _id。

    我们使用这个 _id 来命名一个唯一的会话变量,它将反应性地存储项目的当前查看状态,每当修改这个变量时,模板都会重新呈现。

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2014-04-12
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 2020-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多