好的,这是一个主观的问题,所以如果这看起来像是我喷了两分钱,请原谅我。在我回答你的问题之前,我不得不承认我有点怀疑你:
并不总是有谨慎的 DOM 事件
因为几乎用户可以做的任何事情都会触发您可以观察的事件。例如,如果您想等到用户更改文本输入,则有change
,而且(如您所述)各种key*
事件,还有blur
(通常用于此类事情)。在 3(+) 之间,您应该始终能够适当地响应用户的操作。只有(比如说)您必须每 3 秒保存一次文本输入的内容,它才会真正独立于 DOM 事件。
所以,在不知道你的细节的情况下,我只需要指出那里有什么东西闻起来有腥味。但是无论如何,至于您的实际问题,这是我对您的想法的看法:
在输入元素的按键事件上更新模型
这当然可以,但一定要使用视图来进行实际的事件处理/模型设置;在模型中连接 onKeyPress 处理程序将是一个坏主意
总的来说,这种方法看起来很标准,并且符合 Backbone 范式。
使用模型初始化视图后,让视图更新/向模型添加一个名为“get_input_value()”的函数,该函数返回输入框的值
我不太明白这对你的问题有什么帮助,而且它似乎把问题放在了错误的地方:模型应该(理想情况下)与 DOM 无关。
每当应用程序需要请求模型更新服务器时,首先调用视图中的一个函数,将用户在视图中键入的所有信息更新到模型中。
保存是每 5 分钟发生一次吗?如果不是,那么它可能是为了响应用户的操作而发生的,您应该使用事件处理程序来响应。
但是,如果您确实需要使同步独立于用户操作,我建议您使用自定义事件来管理事情。换句话说,在模型的同步方法中放置类似this.trigger('preSync')
. 然后,使用该模型的每个视图都可以绑定某种updateMyModelValue
方法,即。this.model.on('preSync', this.updateMyModelValue, this);
.
这样,您的模型代码根本不会直接与 DOM 交互;相反,它只是担心它应该担心的东西(数据),并且视图会注意何时需要从 DOM 更新该数据。
希望有帮助。
*编辑(回应您对问题的编辑) *
如果是这种情况,模型必须能够说“用我的观点同步我!”。
模型的一般 Backbone 方式...嗯,它的视图几乎所有内容都是通过事件。
(从技术上讲,您可以在模型本身中维护模型视图的列表,然后遍历该列表以告诉视图执行操作。Backbone 甚至没有足够的意见让您这样做。但是,从可维护性的角度来看,对我来说似乎是一种可怕的方法。)
我的“预同步”事件示例(上图)演示了如何使用这种技术;如果有任何不清楚,请回复评论。
同样,如果您有以下问题:
- 视图 A 捕获事件
- 视图 B 需要做一些事情来响应那个事件
你基本上有两个选择:
1)您可以将两个视图紧密耦合。假设有一个创建行视图的表视图,但需要响应这些行中发生的事件。您可以在创建表时将表本身作为选项传递给行 ( new Row({table:this})
),然后当这些行需要告诉他们的表“发生事件”时,他们可以这样做this.options.table.informThatAnEventHappened()
。如果两个视图本质上是相关的,那么这是一个很好的方法,比如一个表和它的行。如果没有,更好的方法是:
2)您可以使用事件在视图之间进行通信。假设您在页面顶部有一个标题 div,每当“标题”文本输入发生变化时都需要更新它......但是该文本输入在页面下方并且在概念上与页面的标题(除了设置它)。这两个元素(及其视图)之间的共同点是数据,即标题本身的文本。
现在想象 titleDivView 和 titleSettingInputView 都共享一个 pageTitle 模型。当 titleSettingInputView 调用this.model.set('titleText', 'newTitle')
时,titleDivView 可以侦听this.model.on('change:titleText', ...)
,并在响应中适当地重新呈现自己。通过这种方式,两个完全不连接、分离的视图可以相互交互,而不会创建一个相互关联的代码错综复杂的网络。
当然,如果没有一个很方便的“ change:title
”事件可以绑定,你可以自己制作,就像我上面描述的自定义“预同步”事件一样。