我正在使用Backbone.js。在我看来,我有textarea
keyup
绑定到这样的函数(但请参阅下面的编辑):
this.model.save({text: self.$('textarea').val()}, {patch: true});
在视图的initialize
功能中,我将模型的change
事件绑定到视图的render
功能:
initialize: function() {
this.listenTo(this.model, 'change', _.bind(this.render, this));
},
麻烦的是,当用户输入textarea
时,会发生以下事件序列:
keyup
事件触发。keyup
处理程序在模型上调用save
。save
的调用会触发模型的change
事件。change
事件的视图会调用render
。textarea
。textarea
不再聚焦,文本光标位置丢失。对于这种情况,texarea
keyup
事件需要触发同步的最佳做法是什么?我考虑过的一些选择:
change
绑定到render
。缺点:如果模型数据因用户输入以外的任何内容而发生变化,则textarea不会自动更新。render
开头的光标位置。将光标位置设置在render
的末尾。缺点:取决于浏览器支持不稳定的游标操作功能。keyup
处理程序中,在视图上设置一个临时属性,告诉它不要重新渲染。保存模型后取消设置。缺点:感觉像意大利面条代码,与Backbone的结构作斗争。我有没有看到的选择?你推荐上面的一个选项吗?
修改:
我并不想分散注意力,但是因为它出现在其中一个答案中:我没有直接绑定到keyup
,而是将其与{{1}中介}}。因此,事件处理程序仅在用户停止键入时运行,由自上一个_.debounce
以来经过的一定时间量定义。
答案 0 :(得分:1)
首先,我想劝阻这一点,因为在keyup
上保存模型似乎很奇怪。如果有一个用例确实需要这个,我建议至少使用input
事件 - 否则每次用户按下箭头键,shift,ctrl时你最终都会保存模型等
我认为您还希望将输入事件去抖500毫秒左右,实际上并没有保存模型每次单次击键。
在第1点处理你的评论:
缺点:如果模型数据由于除了以外的任何内容而发生变化 用户输入时,textarea不会自动更新
你需要问问自己发生这种情况的可能性,以及如果要发生这种情况,重新审视的重要性。
最后,如果你确定这确实可能是和,那么重新渲染视图很重要,那么你可以试试这样的事情
http://jsfiddle.net/nuewwdmr/2/
此处的重要部分之一是将模型属性名称映射到输入的名称字段。我在这里所做的是遵循你上面描述的一系列事件。不同之处在于,当模型更改时,我们检查更改的属性并更新模板中相应元素的值。
这在一个非常简单的情况下工作正常,这是一个快乐的路径,用户以“正常”的方式输入输入。但是,如果用户决定返回输入的开头并更改字母以将其大写,例如,在模型中发生更改事件后,光标将跳转到字符串的末尾。
这里你需要的行为实际上是双向数据绑定,这绝不是微不足道的,特别是Backbone给出了Backbone View的功能很少。
我的建议是你的观点1
不要将更改绑定到渲染
修改强>
如果您想进一步了解模型/视图绑定,可以查看两个库:
我之前使用过stickit,它很好。不是很好。对于简单绑定是可以的,例如将“顶级”模型属性绑定到输入元素。一旦进入嵌套属性,您将遇到问题,然后您将不得不研究Backbone Deep Model等内容。
就像我说的那样,Backbone的View并没有提供太多功能。如果你有时间我建议使用React组件代替Backbone Views,或者看看ampersand必须提供的一些有趣的东西。