Meteor JS:为特定模板实例存储状态的最佳方式是什么? [英] Meteor JS: What is the best way to store states for a specific template instance?
问题描述
我正在学习 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屋!