Can I pass the this._id value from one template helper to another with Meteor?

青春壹個敷衍的年華 提交于 2019-12-06 11:54:27

问题


I have the following templates (.html) with their respected managers (.js files):

  • adminManageCategories
  • adminAddCategory
  • adminUpdateCategory

Consider the following:

<template name="adminManageCategories">
    {{#each category}}
        <div class="clickme">{{title}}</div>
    {{/each}}

    {{> adminUpdateCategory}}
</template>

Notice the {{> adminUpdateCategory}} is outside of the iteration. This is also a form, and I want to keep it on the same page.

And admin_manage_categories.js

Template.adminManageCategories.events({
    "click .clickme": function(event) {
        event.preventDefault();
        console.log(this._id);
    }
});

Notice the console.log() function, which works, as the template manager is smart enough to know the ID of the item that was clicked.

What I want to do is load this items values into the form when clicked. My example above is slim, but in my real data I have a title, sort order, among other things.

So my question is, what would be the proper way to pass the _id from the adminManageCategories template to the adminUpdateCategory template, which is the form.

I can hack at this with javascript and make things happen, but I think I'm missing a "meteor way" of doing things.

I appreciate the help. Thank you.


回答1:


You need to use a ReactiveVar to store the currently clicked item.

First you need to run meteor add reactive-var, as it's not a package added by default in a standard meteor web app.

JS:

Template.adminManageCategories.created=function(){
  // instantiate the reactive-var in the created callback
  // we store it as a property of the template instance
  this.currentItemId=new ReactiveVar(null);
};

Template.adminManageCategories.helpers({
  // this helper reactively returns the currently clicked item
  currentItem:function(){
    // retrieve the reactive-var from the template instance...
    var currentItemId=Template.instance().currentItemId.get();
    // ...to fetch the correct collection document
    return Items.findOne(currentItemId);
  }
});

Template.adminManageCategories.events({
  "click .clickme": function(event,template) {
    event.preventDefault();
    // assign the correct item id to the reactive-var attached to this template instance
    template.currentItemId.set(this._id);
  }
});

HTML:

<template name="adminManageCategories">
  {{#each category}}
    <div class="clickme">{{title}}</div>
  {{/each}}
  <p>Current item title is : {{currentItem.title}}</p>
  {{! pass the currentItem as a parameter to your child template this will be
      accessible as {{item}} in the HTML and "this.item" in JS helpers or
      "this.data.item" in created/rendered/destroyed callbacks}}
  {{> adminUpdateCategory item=currentItem}}
</template>

EDIT:

When I initialize the reactive-var in the created callback, I set it to null, this means that until one item is clicked, the helper will return null too and when you'll try to access this.item._id in the adminUpdateCategory this will fail.

The simplest way to solve this issue is maybe to not initialize the variable to null but to the first item in the collection.

Template.adminManageCategories.created=function(){
  var firstItem=Items.findOne({},{
    sort:{
      sortedField:1
    }
  });
  this.currentItemId=new ReactiveVar(firstItem && firstItem._id);
};

There may still be a case when you have 0 items in the collection, so you'll probably end up having to guard against the existence of the item in the JS.

Template.adminUpdateCategory.helpers({
  itemProperty:function(){
    return this.item && this.item.property;
  }
});


来源:https://stackoverflow.com/questions/26186219/can-i-pass-the-this-id-value-from-one-template-helper-to-another-with-meteor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!