Meteor应用程序的双向数据绑定

时间:2015-12-03 18:29:17

标签: javascript node.js mongodb meteor data-binding

我已经构建了一个基于表单的应用程序。我想让用户能够部分填写表单,如果他们目前无法完成,请稍后再回来。我已经使用铁路由器为每个表单实例创建一个唯一的URL,因此他们可以回到链接。我的问题是Meteor不会自动保存输入中的值,并且表单在重新访问/刷新时会显示为空白。我尝试了下面的解决方案将数据存储在一个名为“NewScreen”的单独Mongo集合中的临时文档中,然后每次(重新)渲染模板以自动填充表单时引用该文档。但是,我一直收到一个错误,我试图引用的元素是“未定义”。奇怪的是,有时它会起作用,有时则不起作用。我已经尝试过设置一个递归的setTimeout函数,但是在它失败的时候,它也不起作用。任何见解将不胜感激。或者,如果我认为这一切都错了,请随意提出一个不同的方法:

Screens = new Meteor.Collection('screens') //where data will ultimately be stored
Forms = new Meteor.Collection('forms') //Meteor pulls form questions from here
NewScreen = new Meteor.Collection('newscreen') //temporary storage collection
Roles = new Meteor.Collection('roles'); //displays list of metadata about screens in a dashboard

//dynamic routing for unique instance of blank form
Router.route('/forms/:_id', {
  name: 'BlankForm',
  data: function(){ 
    return NewScreen.findOne({_id: this.params._id});
  }
});

//onRendered function to pull data from NewScreen collection (this is where I get the error)
Template.BlankForm.onRendered(function(){
  var new_screen = NewScreen.findOne({_id: window.location.href.split('/')[window.location.href.split('/').length-1]})
  function do_work(){
    if(typeof new_screen === 'undefined'){
      console.log('waiting...');
      Meteor.setTimeout(do_work, 100);
    }else{
      $('input')[0].value = new_screen.first;
      for(i=0;i<new_screen.answers.length;i++){
        $('textarea')[i].value = new_screen.answers[i];
      }
    }
  }
  do_work(); 
}); 

//onChange event that updates the NewScreen document when user updates value of input in the form
'change [id="on-change"]': function(e, tmpl){
      var screen_data = [];
      var name = $('input')[0].value;
      for(i=0; i<$('textarea').length;i++){
        screen_data.push($('textarea')[i].value);
      }

      Session.set("updateNewScreen", this._id);

        NewScreen.update(
          Session.get("updateNewScreen"),
          {$set: 
            {
              answers: screen_data,
              first: name
            }
          });
      console.log(screen_data);
    }

1 个答案:

答案 0 :(得分:0)

如果你得到undefined,那可能意味着findOne()没有找到带有从网址传入的ID的新闻屏幕。要对此进行调查,请添加额外的行,例如console.log(window.location.href.split('/')[window.location.href.split('/').length-1], JSON.stringify(new_screen)); 这将为您提供来自网址的ID和找到的new_screen。

我建议您使用Router.current().location.get().path代替window.location.href,因为您使用了IR。

如果您在客户端中寻找双向绑定,请查看Viewmodel for Meteor