什么是绑定?

16
最近在JavaScript框架如Ember.js,Can.js,Knockout.js和Backbone.js中,以及更传统的Cocoa和Objective-C中,我越来越频繁地看到术语“binding”和“live-binding”,并且我想知道“binding”到底是什么(以及“live-binding”到底是什么)。
大概意思是,我们可以松散地说“将A绑定到B”,然后我们可以说,“A被绑定到B”,这意味着对B所做的更改将自动反映在A中,而无需用户担心设置观察者,但观察者早已自动设置并在B更改时自动通知。
当我们这样做时,我们正在创建一个“binding”。
严格来说,似乎Cocoa和Objective-C将其定义为:对象A的属性foo是一个binding,并且此属性观察对象B的属性bar并随之更改。它是由Observer模式自动实现的,我们不关心它的实现方式,而它应该像黑盒子一样隐藏起来。因此,“binding”实际上意味着“属性”,而不是操作--这个属性观察并与其他属性具有相同的值。
这种binding不仅局限于UI元素绑定到数据,还可以是包含较小UI元素的外部较大UI元素,外部UI元素具有绑定到内部UI元素属性的属性。或者它可以是一个非用户界面数据属性,绑定到另一个非用户界面数据属性。
这就是binding的确切含义吗?那live-binding呢?

4
在我看来,你理解绑定的概念是完全正确的,而"live-binding"只是另一种称呼,基本上意思是相同的。我的观点仅供参考。 - intuitivepixel
1
我认为你已经非常好地回答了自己的问题。 :) - Luke Melia
4个回答

1
我不确定历史,但我猜这个意义上的“binding”一词源于“data-binding”一词。 “data-binding”确实是一个动作:它将UI控件填充为来自实际数据的值,也就是模型。例如,当表单中的字段用来自数据库的数据填充并自动更新时,使用你提到的观察者模式。我认为绑定的主要区别是单向和双向:在双向数据绑定中,用户输入也会被同步回模型,而不仅仅是从模型同步到视图。
“bind”是一个动词,“data-binding”的动词形式可以是“bind data”或“perform data-binding”。第二个例子证明,“data-binding”也是一个名词,它可以定义为“将数据/模型属性绑定到UI/view属性的行为”。关于“binding”本身的名词版本,我认为您正确,它通常指两个属性之间的单个绑定。为了以可视化方式演示这一点,请假设点表示彼此绑定的两个属性:
• ----- •
这里的“binding”是它们之间的线。
更具体地说,单向绑定可以用单个箭头表示:
• ----> •

同时具有双向箭头的双向绑定:

• <---> •

"实时绑定"只是用来表示使用了观察者模式的术语。我猜想,想要区分“实时绑定”的愿望可能来自之前使用过框架的Web开发人员,在这些框架中,数据绑定仅在HTTP请求期间进行一次,即在页面首次加载时进行。现在,随着JavaScript重型Web应用程序成为常态(部分归功于ajax),没有理由不使用原始MVC建议的观察者模式,因此,“实时绑定”对于RIA或本机桌面或移动应用程序来说可能是一个不必要的术语。

顺便说一下,Trygve Reenskaug最初的MVC构想(他发明了它)基本上是关于在系统中反映最终用户的心理模型,以便“模型”几乎是用户直接操纵的内容(或者至少对用户来说感觉是这样)。因此,观察者模式(或至少一些机制,以保持模型和视图同步而无需重新加载页面)是必不可少的,而大多数代码在服务器端的Web开发框架并不真正符合最初的MVC,而是遵循相同的代码组织思路的变体。主要用于客户端应用程序的现代JavaScript框架使真正的MVC对于Web开发成为可能。

回到你在问题中提到的一点,我认为当你说绑定不仅仅是模型属性和视图属性之间的绑定时也是正确的;它可以是两个模型属性之间的绑定(通常在不同的模型上),或者是两个视图属性之间的绑定。但是,我不同意你关于“绑定”仅是编程方面名词的说法 - 显然,在英语中,它是动词“bind”的名词形式,换句话说,“绑定的行为”,而且我认为这在编程中也是一个有效的用法。因此,本质上我是在说它具有双重含义,但我认为你提出的定义是最常见的。以下是我尝试给出的正式定义: 绑定。
  1. 连接两个属性(通常在两个不同的对象中),使这些属性彼此保持同步,即具有相同的值。同步可以是单向或双向的。
  2. 发起这种连接的行为。

如果您对Trygve Reenskaug关于最终用户心理模型的想法感兴趣,我当然建议阅读早期有关MVC的文章,但也要了解他的新编程范式(与MVC互补),DCI,它进一步帮助将用户的心理模型反映到代码中。这篇文章是一个很好的起点。 - Matt Browne
2
请问您能否回答自己的问题,或者接受Matt的答案(我认为非常好)……这样这个问题就可以从“未回答的问题”部分移除了吗?谢谢! :) - Julian Leviston

0
绑定在非常简单的意义上意味着链接,假设您有一个进度条和一个变量X,每次您点击按钮时,X的值都会增加。使用绑定,您可以获取X的值(每次它增加)并显示在进度条上。在以下C#代码行中,“pb”是进度条,而“TapCount”是保存总点击次数的变量。它显示了“pb”的值已经绑定到变量TapCount。
public void tapping
{    
 pb.Value = TapCount; 
}

0

“绑定”这个术语主要用于客户端开发。例如,您创建了一个显示温度的HTML网页。

<div id="temp_value"> 77 °F </div>

现在,您希望在不断向温度提供程序 API 发送 AJAX 请求的同时更新此值,以响应温度变化。在该响应中,您将收到一个温度值,该值应相应地更新您的 UI。

这个需要使用 Javascript 变量或类似方法来更新 HTML 的概念被称为绑定。

当您创建一个东西,使得您的 DOM 与任何可以是 DOM - 变量对的 JS 变量中的更改保持同步时,可以将其称为绑定。

还有一个称为双向绑定的术语,其中 DOM 中的任何更改都会更新绑定的 JS 变量,反之亦然。


0

这与原始的JavaScript中 .bind 方法的使用方式并没有太大区别:您将对象的作用域绑定到方法。

考虑下面这两个代码片段:this.iterable.map( this.flush )this.iterable.map( this.flush.bind(this))。在第一个代码片段中,我们只是在每次迭代该属性时运行一个方法,但是为了让this.flush方法可以访问this属性,您必须将它绑定到this

同样,在像Ember这样的框架中,model是一种声明。为了从远程源填充该模型,您需要一个实例。为了从handlebars修改模型,您需要一个实例。如果UI更改立即影响模型实例-它们就被绑定了。

伪代码: UI.view.bind(modelInstance) RemoteSource.bind(modelInstance)

“Live-Binding”,在我的经验中,是数据在UI中更改时立即绑定到远程源。

伪代码: UI.view.bind(modelInstance) RemoteSource.bind(modelInstance) modelInstance.onChange(RemoteSource.update.bind(modelInstance))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接