Meteor JS:为特定模板实例存储状态的最佳方式是什么? [英] Meteor JS: What is the best way to store states for a specific template instance?

查看:46
本文介绍了Meteor JS:为特定模板实例存储状态的最佳方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习 Meteor JS 中的会话和反应式数据源.它们非常适合设置全局 UI 状态.但是,我不知道如何将它们限定到模板的特定实例.

这就是我想要做的

我在一个页面上有多个 contenteditable 元素.每个下方都有一个编辑"按钮.当用户单击编辑"按钮时,它应该关注元素并显示保存"和取消"按钮.

如果用户单击取消",则所有更改都将被消除,模板实例应使用原始内容重新呈现.

这是我目前的代码

//助手Template.form.helpers({编辑状态:函数(){返回 Session.get("editState");}});//渲染Template.form.rendered = function(e){var $this = $(this.firstNode);var formField = this.find('.form-field');if (Session.get("editState")) formField.focus();};//事件映射模板.form.events({'点击 .edit-btn':函数(e,模板){e.preventDefault();Session.set("editState", "is-editing");},'点击 .cancel-btn':函数(e,模板){e.preventDefault();Session.set("editState", null);},});//模板<模板名称=表单"><div class="{{editState}}"><p class="form-field" contenteditable>{{描述文本}}</p>

<a href="#" class="edit-btn">编辑</a><a href="#" class="save-btn">保存</a><a href="#" class="cancel-btn">取消</a>//CSS.edit-btn.cancel-btn,.save-btn {显示:内联块;}.cancel-btn,.save-btn {显示:无;}.is-editing .cancel-btn,.is-editing .save-btn {显示:内联块;}

问题

如果我有多个 Form 模板的实例,那么 .form-field 会关注每个实例,而不仅仅是正在编辑的那个.如何让只有被编辑的人获得焦点?

解决方案

您可以使用 data 渲染模板,它基本上只是插入页面时传递给它的对象.

>

数据可能只是在 Session 中用于 editState 的关键.

例如,使用 Template.form({editStateKey:'editState-topForm'})

渲染模板

你可以制作一个把手助手,例如,

Handlebars.registerHelper('formWithOptions',功能(编辑状态键){返回 Template.form({editStateKey:editStateKey})});

然后使用

将其插入到您的模板中

{{{formWithOptions 'editState-topForm'}}}(注意三元组 {, })

接下来,将引用从 Session.x('editState') 更改为 Session.x(this.editStateKey)/Session.x(this.data.editStateKey)

Template.form.helpers({编辑状态:函数(){返回 Session.get(this.editStateKey);}});//渲染Template.form.rendered = function(e){var $this = $(this.firstNode);var formField = this.find('.form-field');if (Session.get(this.data.editStateKey)) formField.focus();};//事件映射模板.form.events({'点击 .edit-btn':函数(e,模板){e.preventDefault();Session.set(this.editStateKey, "正在编辑");},'点击 .cancel-btn':函数(e,模板){e.preventDefault();Session.set(this.editStateKey, null);},});

注意:如果您使用 iron-router,它有额外的 api 用于将 data 传递给模板.

注2:在meteor 1.0 中,应该会更好地支持编写自己的小部件.这应该可以更好地控制此类事情.

I'm learning about Session and reactive data sources in Meteor JS. They work great for setting global UI states. However, I can't figure out how to scope them to a specific instance of a template.

Here's what I'm trying to do

I have multiple contenteditable elements on a page. Below each is an "Edit" button. When the user clicks on the Edit button, it should focus on the element and also show "Save" and "Cancel" buttons.

If the user clicks "Cancel", then any changes are eliminated, and the template instance should rerender with the original content.

Here's the code I have so far

// Helper
Template.form.helpers({
  editState: function() {
    return Session.get("editState");
  }
});

// Rendered
Template.form.rendered = function(e){
  var $this = $(this.firstNode);
  var formField = this.find('.form-field');
  if (Session.get("editState")) formField.focus();
};

// Event map
Template.form.events({
  'click .edit-btn' : function (e, template) {
    e.preventDefault();
    Session.set("editState", "is-editing");
  },

  'click .cancel-btn' : function (e, template) {
    e.preventDefault();
    Session.set("editState", null);
  },
});

// Template
<template name="form">
  <div class="{{editState}}">
    <p class="form-field" contenteditable>
      {{descriptionText}}
    </p>
  </div>
  <a href="#" class="edit-btn">Edit</a>
  <a href="#" class="save-btn">Save</a>
  <a href="#" class="cancel-btn">Cancel</a>
</template>


// CSS
.edit-btn
.cancel-btn,
.save-btn {
  display: inline-block;
}

.cancel-btn,
.save-btn {
  display: none;
}

.is-editing .cancel-btn,
.is-editing .save-btn  {
  display: inline-block;
}

The problem

If I have more than one instance of the Form template, then .form-field gets focused for each one, instead of just the one being edited. How do I make so that only the one being edited gets focused?

解决方案

You can render a template with data, which is basically just an object passed to it when inserted in to a page.

The data could simply be the key to use in the Session for editState.

eg, render the template with Template.form({editStateKey:'editState-topForm'})

you could make a handlebars helper eg,

Handlebars.registerHelper('formWithOptions', 
  function(editStateKey){
    return Template.form({editStateKey:editStateKey})
});

then insert it in your template with

{{{formWithOptions 'editState-topForm'}}} (note the triple {, })

Next, change references from Session.x('editState') to Session.x(this.editStateKey)/ Session.x(this.data.editStateKey)

Template.form.helpers({
  editState: function() {
    return Session.get(this.editStateKey);
  }
});

// Rendered
Template.form.rendered = function(e){
  var $this = $(this.firstNode);
  var formField = this.find('.form-field');
  if (Session.get(this.data.editStateKey)) formField.focus();
};

// Event map
Template.form.events({
  'click .edit-btn' : function (e, template) {
    e.preventDefault();
    Session.set(this.editStateKey, "is-editing");
  },

  'click .cancel-btn' : function (e, template) {
    e.preventDefault();
    Session.set(this.editStateKey, null);
  },
});

Note: if you are using iron-router it has additional api's for passing data to templates.

Note2: In meteor 1.0 there is supposed to be better support for writing your own widgets. Which should allow better control over this sort of thing.

这篇关于Meteor JS:为特定模板实例存储状态的最佳方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆