当讨论视图的时候,我们非常依赖于DOM。讨论控制器的时候,我们受到浏览器事件模型的限制。而编写模型的时候,我们几乎纯粹与JavaScript打交道,而与特定于浏览器的功能毫无关系。那些饱受浏览器的不兼容性和各种bug痛苦的人都会承认,这是一种舒适的状态。
让我们看一个简单的例子。在第3章,我们曾以从服务器生成数据的观点讨论了服装店应用。描述服装类型列表的数据,包括唯一ID、名称、描述,还有价格、色彩、尺寸信息。现在让我们回到这个例子,考察当客户端收到数据时会发生什么。在其生命周期过程中,应用将会收到很多这样的数据流,并且需要将数据保存在内存中。如果你喜欢,可以将其看作是一个缓存——保存在客户端的数据可以很快显示,而不需要在用户请求数据的时候回到服务器去获取。这对于改善用户的工作流是有好处的,就像在第1章中讨论的那样。
我们可以定义一个简单的JavaScript对象,对应于服务器端定义的garment对象。代码清单4-10显示了一个典型的例子。
代码清单4-10 Garment.js
var garments=new Array();
function Garment(id,title,description,price){
this.id=id;
garments[id]=this;
this.title=title;
this.description=description;
this.price=price;
this.colors=new Object();
this.sizes=new Object();
}
Garment.prototype.addColor(color){
this.colors.append(color,true);
}
Garment.prototype.addSize(size){
this.sizes.append(size,true);
}![]()
我们首先定义了一个全局数组,用来保存所有的服装(没错,全局变量是危险的。在生产环境中,我们应该使用一个名字空间对象,但是在这里为了清楚起见而省略了)。这是一个关联数组,服装的唯一ID作为键,保证我们在同一时间对于每种服装类型只有一个引用。在构造函数中,我们设置所有简单的属性,即那些不是数组的属性。我们将数组定义为空,并且提供简单的添加方法,这些方法使用增强的数组代码(参见附录B)来避免重复。
没有默认提供获取或设置方法,也不像一个完整的面向对象语言做的那样,支持完全的访问控制——私有、受保护和公有变量及方法。有很多方法可以提供这个特征,这些方法在附录B中讨论,但是我自己偏向于保持简单的模型。
当解析XML数据流的时候,一开始创建一个空的Garment对象,然后逐个字段组装它,是很好的方法。敏锐的读者可能奇怪,为什么我们没有提供一个更简单的构造函数。实际上,JavaScript函数的参数是可变的,当调用一个函数时,任何缺少值的参数会简单地初始化为null。所以调用
var garment=new Garment(123);
将被看作与以下调用等同:
var garment=new Garment(123,null,null,null);
我们必须要传进ID,因为在构造函数中要使用它以便在全局garment列表中放置新的对象。







