Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Meteor JS:存储特定模板实例状态的最佳方法是什么?_Javascript_Meteor - Fatal编程技术网

Javascript Meteor JS:存储特定模板实例状态的最佳方法是什么?

Javascript Meteor JS:存储特定模板实例状态的最佳方法是什么?,javascript,meteor,Javascript,Meteor,我正在学习Meteor JS中的会话和反应数据源。它们非常适合设置全局UI状态。但是,我不知道如何将它们限定到模板的特定实例 以下是我正在尝试做的 我在一个页面上有多个contenteditable元素。每个按钮下面都有一个“编辑”按钮。当用户单击编辑按钮时,它应该关注元素,并显示“保存”和“取消”按钮 如果用户单击“取消”,则任何更改都将被消除,模板实例应使用原始内容重新提交 这是我目前掌握的代码 // Helper Template.form.helpers({ editState: f

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

以下是我正在尝试做的

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

如果用户单击“取消”,则任何更改都将被消除,模板实例应使用原始内容重新提交

这是我目前掌握的代码

// 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;
}
//助手
Template.form.helpers({
editState:函数(){
return Session.get(“editState”);
}
});
//渲染
Template.form.rendered=函数(e){
var$this=$(this.firstNode);
var formField=this.find('.formField');
if(Session.get(“editState”))formField.focus();
};
//事件图
Template.form.events({
“单击。编辑btn”:函数(e,模板){
e、 预防默认值();
Session.set(“editState”,“正在编辑”);
},
“单击。取消btn”:函数(e,模板){
e、 预防默认值();
Session.set(“editState”,null);
},
});
//模板

{{descriptionText}}

//CSS .编辑btn .取消btn, .保存btn{ 显示:内联块; } .取消btn, .保存btn{ 显示:无; } .正在编辑。取消btn, .正在编辑。保存btn{ 显示:内联块; }
问题


如果我有多个
表单
模板的实例,那么
.Form字段
将为每个实例聚焦,而不仅仅是正在编辑的实例。如何使被编辑的模板聚焦?

您可以使用
数据呈现模板,这基本上只是插入页面时传递给模板的对象

数据可能只是
会话
编辑状态
使用的关键

例如,使用
template.form({editStateKey:'editState-topForm'})呈现模板

你可以做一个把手助手,例如

Handlebars.registerHelper('formWithOptions', 
  function(editStateKey){
    return Template.form({editStateKey:editStateKey})
});
然后将其插入到模板中,并使用

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

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

注意:如果您使用的是
iron router
,它有额外的api用于将
数据
传递到模板


注2:在Meteor1.0中,应该有更好的支持来编写自己的小部件。这应该可以更好地控制这类事情。

作为一项政策,我几乎在所有情况下都避免会话。我觉得随着应用程序的增长,它们的全球范围会导致坏习惯和缺乏关于分离关注点的良好规范。此外,由于会话的全局作用域,在呈现模板的多个实例时,会话可能会导致问题。出于这些原因,我觉得其他方法更具可扩展性

替代办法

1 addClass/removeClass 您可以直接执行所需的操作,而不是设置一个状态然后在其他地方对其作出反应。此处,类根据需要显示和隐藏块:

'click .js-edit-action': function(event, t) {
    var $this = $(event.currentTarget),
    container = $this.parents('.phenom-comment');

    // open and focus
    container.addClass('editing');
    container.find('textarea').focus();
},

'click .js-confirm-delete-action': function(event, t) {
      CardComments.remove(this._id);
},
2范围为模板实例的ReactiveVar

3铁路由器的状态变量 得到

设置

4收集数据 另一种方法是简单地通过更新集合中的数据来声明。有时候,这很有道理

5更新数据上下文
在我看来,会话往往是更糟糕的选择。此外,我个人不使用#3,因为我觉得如果我们想切换到另一个路由器包(如“Flow”)时,与iron router的联系越少越好。

谢谢,我对
editState topform
的来源有点困惑。我刚刚偶然发现了一个类似问题的解决方案,它采用将模板实例的id放入会话对象的方法。这个答案是假设您正在重新使用
表单
模板,并且每次都需要使用不同的选项(即要使用的
会话
的名称)对其进行实例化。如果使用不同的模板,但一次只需要一个可编辑的模板。更好的解决方案是将活动的“模板”存储在会话变量中。
'click .js-edit-action': function(event, t) {
    var $this = $(event.currentTarget),
    container = $this.parents('.phenom-comment');

    // open and focus
    container.addClass('editing');
    container.find('textarea').focus();
},

'click .js-confirm-delete-action': function(event, t) {
      CardComments.remove(this._id);
},
if (Meteor.isClient) {  
  Template.hello.created = function () {
  // counter starts at 0
  this.counter = new ReactiveVar(0);
};

Template.hello.helpers({
  counter: function () {
  return Template.instance().counter.get();
  }
});

Template.hello.events({
  'click button': function (event, template) {
    // increment the counter when button is clicked
    template.counter.set(template.counter.get() + 1);
  }
});
}
Router.route('/posts/:_id', {name: 'post'});

PostController = RouteController.extend({
  action: function () {
    // set the reactive state variable "postId" with a value
    // of the id from our url
    this.state.set('postId', this.params._id);
    this.render();
  }
});
Template.Post.helpers({
  postId: function () {
    var controller = Iron.controller();

    // reactively return the value of postId
    return controller.state.get('postId');
  }
});