随笔-312  评论-11933  文章-2  trackbacks-230
English Version: http://dflying.dflying.net/1/archive/109_atlas_unleashed-bindings.html

Atlas架构提供了一种比ASP.NET中数据绑定(data binding)强大得多的客户端绑定模型。这种模型异常灵活,甚至有些类似WPFWindows Presentation Foundation)中的绑定模型。Atlas提供的绑定模型允许您将某对象的任意一个属性绑定到另外一个对象的任意一个属性上。它不单单可以应用于数据绑定,甚至可以将某个控件的样式绑定到另外一个控件上。这样使得在Atlas中将一切关联起来变成可能。

在这个帖子中,我将尝试分析一些Atlas实现代码来解释Atlas是如何完成Binding的。

首先让我们察看一小段应用Atlas Binding的代码。这里将一个textboxtext属性和一个select listselectedValue属性绑定起来。无论你改变其中的哪个,在另一个上面都会有立刻得到体现。

HTMLASPX,定义textboxselect list。(注意必须声明一个ScriptManager服务器端对象,以引入Atlas必须的JavaScript文件。)

<atlas:ScriptManager ID="ScriptManager1" runat="server" />
<div>
    Input an integer from 1 to 5.
<br />
    
<input id="myTextBox" type="text" /><br />
    Select an item.
<br />
    
<select id="mySelect">
        
<option value="1">value 1</option>
        
<option value="2">value 2</option>
        
<option value="3">value 3</option>
        
<option value="4">value 4</option>
        
<option value="5">value 5</option>
    
</select>
</div>

 

Atlas脚本,将上面两个HTML控件“升级”成Atlas控件。

<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
    
<references>
    
</references>
    
<components>
        
<textBox id="myTextBox">
            
<bindings>
                
<binding dataContext="mySelect" dataPath="selectedValue" property="text" direction="InOut" />
            
</bindings>
        
</textBox>
        
<select id="mySelect" />
    
</components>
</page>

 

如上所示,我们只需要书写一小段简单的代码即可实现需要的绑定功能。

Atlas是如何实现这些的呢?首先,Atlas需要有一种途径来监听绑定控件的绑定属性的变化(除非你不需要Atlas提供的自动绑定功能)。在Atlas.js中定义了一个名为Sys.INotifyPropertyChanged的接口,类似.NET中提供的一样。对象可以实现这个接口以期让别的对象监听到自己的属性值的变化。Atlas中所有组件的基类,Sys.Component,实现了这个接口。Sys.Component同样提供一个方法raisePropertyChanged(propertyName),这个方法应该在每个属性的setter中被调用以发出INotifyPropertyChanged.propertyChanged事件。

目前为止,我们可以看一下Atlas控件中textbox的具体实现。看看textbox中是如何在相应的HTML事件发出时同样发出propertyChanged事件的。

var _text;
var _changeHandler;

this.get_text = function() {
    
return this.element.value;
}


this.set_text = function(value) {
    
if (this.element.value != value) {
        
this.element.value = value;
        
this.raisePropertyChanged('text');
    }

}


this.initialize = function() {
    Sys.UI.TextBox.callBaseMethod(
this, 'initialize');
    
    _text 
= this.element.value;

    _changeHandler 
= Function.createDelegate(thisthis._onChanged);
    
this.element.attachEvent('onchange', _changeHandler);
    
    _keyPressHandler 
= Function.createDelegate(thisthis._onKeyPress);
    
this.element.attachEvent('onkeypress', _keyPressHandler);
}


this._onChanged = function() {
    
if (this.element.value != _text) {
        _text 
= this.element.value;
        
this.raisePropertyChanged('text');
    }

}

 

可以看到,当text属性改变时,Atlas发出了propertyChanged事件,这就使绑定到这个属性成为可能。

而后Atlas的绑定模型捕获到了这个事件,再根据binding声明查找出与其相关的目的对象以及相应的属性,并调用这个属性的Setter来实现目的对象属性的变化。

 

如果源对象(source object)实现了INotifyPropertyChanged接口,并且改变的属性就是dataPath 中指定的属性,同时direction 设定为In或者InOutAtlas绑定将通过分析引入(incomingbinding来处理propertyChanged事件(参考下面将要介绍的evaluateIn()方法)。

类似的,如果目的对象(target object)实现了INotifyPropertyChanged接口,并且改变的属性就是property中指定的属性,同时direction 设定为Out或者InOutAtlas绑定将通过分析流出(outgoingbinding来处理propertyChanged事件(参考下面将要介绍的evaluateOut()方法)。

 

接下来让我们察看binding实现代码中的的公有方法和属性来分析一下Atlas绑定的核心实现。在这里没有必要列出涉及绑定的全部代码,如果您感兴趣,可以用关键词Sys.BindingBaseSys.Binding Atlas.js文件中进行搜索。首先是Sys.BindingBase提供的方法和属性。

 

  1. 属性automatic:指定当源对象的相应属性变化时(对于In和InOut),或者目的对象的相应属性变化时(对于Out和InOut),绑定是否将被自动执行。这个属性默认会被置为true。当然如果你需要完全控制绑定的开始时机时也可以设定为false。例如,某些情况下你决定在一个AJAX请求成功返回的时候才开始绑定数据源与显示控件,以确保显示控件真正绑定到了一些数据,这时你需要显示的调用binding的evaluate()方法以开始绑定。
  2. 属性dataContext:指定拥有待绑定属性的对象。如果不指定的话,Atlas binding将调用包含它的父控件的dataContext属性代替。控件可以通过返回设定的dataContext或是按照默认返回其父控件的dataContext来实现这个属性。例如,某个ListView控件可以在其创建ListView Item时设定它的dataContext为一个DataRow对象,以实现绑定。
  3. 属性dataPath:指定需要绑定的源对象的属性。Atlas binding还允许绑定一个嵌套的属性,类似:sourceObjectProperty.nestedProperty.nestedNestedProperty。源代码中可以看出Atlas能自动为你转化并运行这些代码。dataPath属性的默认值为空,也就是Atlas会绑定这个对象本身。
  4. 属性property:指定需要绑定的目标对象的属性。你应该总是指定这个属性,否则这个绑定就没有任何意义。
  5. 属性propertyKey:有时候我们可能需要绑定到某个对象的嵌套属性上。比如,如果需要绑定到style的属性color,我们可以指定property属性为style,并指定propertyKey属性为color。
  6. 属性transformerArgument:传递给Atlas transformer的参数,只有设定transform时才会用到。
  7. 事件transform:这个事件允许在绑定时指定一个transformer。当你需要在绑定的时候对数据做以处理时,transformer将会是个很好的选择。例如,如果你希望显示一个布尔值为Yes/No而不是默认的true/false,那么就应该使用一个自定义的transformer。Atlas同时提供了一些内建的transformer,例如Add,Multiply以及Compare等。
  8. 方法evaluateIn:处理引入的binding。如果direction属性设置成为In或者InOut,该方法将取得源对象的属性的值(根据binding中设定的dataContext以及dataPath属性),并调用目标对象相应属性的Setter。这也就是Atlas中实现binding的核心部分。  

Sys.Binding(也在Atlas.js中)中也有一些重要的方法/属性:

 

  1. 属性direction:指定希望监听的属性变化的方向。可以设定为InOut或者InOut。默认值为In
  2. 方法evaluateOut:与基类中的方法evaluateIn类似,但是以相反的方向执行。当然,需要将directiton属性设定为Out或者InOut
希望这些解释能够让您对Atlas的“神奇的”绑定有一些更深入的理解。欢迎留言探讨。

PS:这篇文章中有些英文不知道应该如何用中文表示,希望能得到一些建议以及指正:

  1. evaluate,我翻译成“处理”,但文中还有“计算求值”的意思,这一点没有体现出来。
  2. incomingoutgoing,我翻译成“引入”和“流出”……觉得不是一般的别扭。
  3. transformer,没有翻译(实在不知道怎么说了)。
  4. gettersetter,没有翻译(一直都不知道怎么翻译)。
posted on 2006-04-04 20:34 Dflying Chen 阅读(3875) 评论(43)  编辑 收藏 网摘 所属分类: ASP.NET AJAX (Atlas)

评论:
#1楼  2006-04-04 22:19 | 一般 [未注册用户]
没有什么新意
  回复  引用    
#2楼  2006-04-04 23:15 | mmt [未注册用户]
用UpdataPanel更加容易吧
  回复  引用    
#3楼  2006-04-04 23:39 | 阿不      
先支持一下,目前主要是使用以服务器端为中心的开发模式。对客户端的开发模型还不是很熟悉,等过一段时间进度比较松,而且有这样的需求的时候再做深入研究。
  回复  引用  查看    
#4楼 [楼主] 2006-04-05 09:00 | Dflying Chen      
@阿不
看看上面两个评论,发现有些人认识太浅薄(允许我用这个词)了。国内技术的进度总是要比国外慢那么一段时间,就是因为抱有这种思想的国内程序员还不少的原因吧。对于Atlas,大部分人还都在只关心UpdataPanel的程度上……
  回复  引用  查看    
#5楼  2006-04-05 09:11 | 阿不      
呵呵,使用客户端的开发方式执行效率上肯定会更好,但是使用了全新的页面事件模型和编写方式,开发难度也是相对比较复杂些,但这相对于让我们直接去编写原生的Ajax应用,应该简单不少,我们只是去应用别人的开发成果,没有理由做得不好。目前我们也主要是使用UpdatePanel,也是由于我们目前团队的创新能力和学习能力上的不足。
  回复  引用  查看    
#6楼 [楼主] 2006-04-05 09:20 | Dflying Chen      
@阿不
本来想继续写一些深入的文章,这样看来还是先写简要介绍吧,呵呵。
  回复  引用  查看    
#7楼  2006-04-05 09:44 | 阿不      
@Dflying Chen
不会呀,我觉得写一些深入的文章比较好,如果使用UpdatePanel比较简单,大家只要看一下DEMO就可以了。而像你在文中提到的这些可能都是目前大家比较少接触到的,比如如何写xml-script脚本,控件都有哪些可以操作的属性,等等,毕竟目前这方面的文档还是比较少的。
  回复  引用  查看    
#8楼  2006-04-05 09:57 | Terrylee      
介绍的很好,我也很想学习这方面的东西,可惜时间太紧了
楼主的这些Atlas文章我都收藏了,过段时间好好研究一下,呵呵

希望楼主能继续写一些深入的文章,现在很多人的关注都在应用的层次上,就像你说的还停留在关注UpdatePanel上一样,这一点从很多文章的阅读量就可以看出来。
  回复  引用  查看    
#9楼 [楼主] 2006-04-05 10:16 | Dflying Chen      
@阿不
@Terrylee
由浅入深都写一点吧,呵呵 :)
谢谢支持。
  回复  引用  查看    
#10楼  2006-04-05 12:29 | wen3062 [未注册用户]
支持~~
  回复  引用    
#11楼  2006-04-09 08:23 | lauralxj [未注册用户]
我都把你的文章贴到富士康内部论坛里面了,呵呵,关于asp.net 2.0 Atlas 支持多写点,谢谢
  回复  引用    
#12楼 [楼主] 2006-04-09 08:35 | Dflying Chen      
@lauralxj
见笑了,随便写点而已,仅供参考。
  回复  引用  查看    
#13楼  2006-04-19 22:59 | kane      
写得很不错,支持了。
InComing和Outgoing翻译为传入,传出如何?
Transformer翻译为转换如何,或者转换器?
  回复  引用  查看    
#14楼 [楼主] 2006-04-19 23:08 | Dflying Chen      
@kane
传入,传出确实比我的翻译好多了,谢谢!
Transformer其实就是转换器,但是只是叫转换器似乎有点太泛化了……
谢谢支持
  回复  引用  查看    
#15楼  2006-04-20 00:19 | kane      
呵呵,既然就是转换器,而且大家都能看得懂,那就叫转换器好了。感觉Ajax本来一个很简单的东西,竟由此引申出这么庞大的一个框架来。还有prototype,Infragistics也有自己的一套Client类库。博客园里又有了jsvm团队。感觉有些乱了。
  回复  引用  查看    
#16楼 [楼主] 2006-04-20 08:53 | Dflying Chen      
@kane
那就叫转换器吧:)
AJAX其实很复杂的……Hello World很容易,但是实际开发的时候麻烦死了
  回复  引用  查看    
#17楼  2006-04-20 10:04 | shalala      
哈哈,说得好,的确麻烦啊。
什么时候开发web就好像开发vb一样简单就好了
  回复  引用  查看    
#18楼 [楼主] 2006-04-20 10:26 | Dflying Chen      
@shalala
不是很容易吧
  回复  引用  查看    
#19楼  2006-04-20 16:14 | kane      
@Dflying Chen
是啊。在现有的javascript的基础上弄出一个既强大又优雅的东西确实不是很容易。想起cgi刚出现的年代了~~
  回复  引用  查看    
#20楼 [楼主] 2006-04-20 19:01 | Dflying Chen      
@kane
呵呵,需要一种革命的东西。
  回复  引用  查看    
#21楼  2006-04-21 09:47 | www.fcsoft.com.cn [未注册用户]
好文收藏!! (开源的基于AJAX的自定义表单工具,在 www.fcsoft.com.cn )
  回复  引用    
#22楼 [楼主] 2006-04-21 10:00 | Dflying Chen      
@www.fcsoft.com.cn
广告?
  回复  引用  查看    
#23楼  2006-05-08 17:52 | 閮界潱 [未注册用户]
不大明白,客户脚本写在哪?怎么就知道脚本里的this就是myTextBox呢?
在set_text下写this.raisePropertyChanged('text')那么在onchanged事件下会不会反复调用啊。有这篇文章的DEMO吗?可不可以把他发给我。官方网站好象没有js和Atlas脚本混用的例子吗。
2zhk@163.com
  回复  引用    
#24楼 [楼主] 2006-05-08 18:00 | Dflying Chen      
@閮界潱
Atlas客户端控件初始化时会传入一个相关的DOM元素,Atlas把它和JavaScript对象连接起来,通过this访问到JavaScript对象之后即可找到对应的DOM元素。
onchanged事件下会不会反复调用?这个问题没明白你的意思。
本文没有相关的DEMO。
官方网站上面有好多js和Atlas脚本混用的例子的。
  回复  引用  查看    
#25楼  2006-06-02 16:10 | Sunny      
弱问:atlas软件包在哪里可以下载?怎么找不到
  回复  引用  查看    
#26楼 [楼主] 2006-06-02 16:29 | Dflying Chen      
@Sunny
在atlas.asp.net
  回复  引用  查看    
#27楼  2006-06-05 09:06 | 阿非      
支持一下~~
  回复  引用  查看    
#28楼 [楼主] 2006-06-05 09:10 | Dflying Chen      
@阿非
谢谢
  回复  引用  查看    
#29楼  2006-06-26 16:57 | 阿不      
这边提到的几个名词的翻译问题,我随便也提几个,一直不知道如何翻译,Dflying帮忙翻译一下:
Mashup
Gadget

  回复  引用  查看    
#30楼 [楼主] 2006-07-04 16:09 | Dflying Chen      
@阿不
我觉得对于这种单词还是保留英文比较好……
  回复  引用  查看    
#31楼  2006-07-10 14:44 | killuakun [未注册用户]
支持,前2天想研究AJAX,找到了atlas找到了你,从你的BLOG里找到了大量资料,你的分享相当有价值!
我想知道xml-script这东西具体该如何编写呢,或者我在哪里能找到相关资料?看了几天atlas.asp.net,对上面的一些简单例子尝试了一下,感觉和直接写客户端JS区别不小,也许我对那个更习惯点吧.
  回复  引用    
#32楼  2006-07-10 15:09 | killuakun [未注册用户]
<textBox id="myTextBox">
<bindings>
<binding dataContext="mySelect" dataPath="selectedValue" property="text" direction="InOut" />
</bindings>
</textBox>
<select id="mySelect" />
------------------------------------------
<select id="mySelect">
<bindings>
<binding dataContext="myTextBox" dataPath="value" property="value" direction="InOut" />
</bindings>
</select>
<textBox id="myTextBox" />
------------------------------------------
我还以为上一段和下一段效果会一样呢,下一段报错说没有value这个属性.这里该怎么写呢?需要xml-script的资料~~
  回复  引用    
#33楼 [楼主] 2006-07-21 18:33 | Dflying Chen      
@killuakun
<binding dataContext="myTextBox" dataPath="text" property="selectedValue" direction="InOut" />
  回复  引用  查看    
#34楼 [楼主] 2006-07-21 18:33 | Dflying Chen      
@killuakun
目前尚没有完全的官方文档,唯一可能的就是自己摸索了。或是大家讨论。
  回复  引用  查看    
#35楼  2006-07-28 10:41 | a_a      
收~ 非常感谢!
  回复  引用  查看    
#36楼 [楼主] 2006-08-05 09:07 | Dflying Chen      
@a_a
:)
  回复  引用  查看    
#37楼  2006-09-04 23:25 | Eilien [未注册用户]
说得很详细,我要打好基础,就要这样细节方面的东东。谢谢了。
  回复  引用    
#38楼 [楼主] 2006-09-05 00:06 | Dflying Chen      
@Eilien
这些就是实现原理了,真正开发的时候不大能用上的。
  回复  引用  查看    
#39楼  2006-10-01 04:22 | 戴南      
我觉得关注在应用层次上没错
不过那只是个堆码的人应该注意的
我认为Chen的出发点和角度都是值得我借鉴和思考的
一个想要发展的人应该要站在更高的层次上去看问题
生活如此,技术亦如此.~
支持~~!
多发些这样的文章.
  回复  引用  查看    
#40楼 [楼主] 2006-10-02 14:54 | Dflying Chen      
@戴南
恩,谢谢支持!现在是没有时间啊……以后空了的时候多写点!
  回复  引用  查看    




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-05-09 12:03 编辑过
Google站内搜索

相关文章:

相关链接: