本节书摘来自异步社区《ember.js实战》一书中的第2章,第2.5节,作者:【挪】joachim haagen skeie(乔基姆•哈根•斯基)著,更多章节内容可以访问云栖社区“异步社区”公众号查看
ember.js扩展了javascript默认对象类的定义,以构建一个更强大的对象模型。此外,ember.js还支持基于混入类的方式,在模块与模块之间、应用与应用之间共享代码。
你可能想了解ember.js是怎样知道某个属性发生改变的,以及它何时触发观察者函数和绑定对象。同时你可能还注意到,ember.js总是要求使get()和set()方法来获取或修改ember.object子类对象的属性。当在一个属性上调用set()方法,ember.js就会检查更新值与对象原有属性值是否不同,如果不同,ember.js就会触发绑定对象、观察者函数或者计算属性函数。
尽管刚接触ember.js时使用get()和set()方法看起来可能有点不习惯,但这却是确保ember.js统一智能处理观察者、绑定、计算属性以及dom操作的重要机制。实际上,使用get()和set()方法是ember.js解决涉及多个dom元素更新及绑定性能问题的重要基础。
创建自定义ember.js对象通常有两种方式,要么通过extend()方法扩展其他ember.js对象并添加自定义功能,要么用create()方法创建一个ember.js对象实例。无论选择哪种方式,应用程序中创建的每个对象都以某种方式扩展自ember.object类,ember.object是基础类,其确保ember.js能够提供本书涉及的所有功能。
想像一下,不通过扩展ds.model来实现notes.note模型对象,绕开ember data,自己实现一个notes.note模型,如代码清单2-9所示。
代码清单2-9 创建notes.note对象

不像使用ember.object.create()创建一个匿名note实例,这里通过扩展ember.object类创建了一个显式的notes.note类。注意以下两点。
现在还没有notes.note类的实例,因为extend()方法并不`返回一个实例。
note类开始于大写的“n”,这个记号对于你,乃至ember.js框架,都意味着note是一个类定义,而非对象实例。
要创建notes.note类的新实例,请使用create()方法:
这时你可能会认为,我们仍看不到这种方式优于匿名ember.object.create()实现的地方。但是,对于ember.js应用中用到的所有数据类型和对象而言,显式定义类通常是个好主意。即使这么做需要更多的代码,但你清晰地展示了实例化一个对象的意图,并且可以明确分隔各个业务模型对象。最终代码可读性强、更易于维护,而且容易测试。
明确定义应用程序对象还使得在正确的地方添加观察者、绑定以及计算属性变得容易,并确保应用快速应变。考虑这样一个场景,原先后台应用为每个note对象的value属性提供了纯文本实现方式,以将属性值编码成markdown格式,但现在要编码成html格式了。如代码清单2-10所示,如果在应用程序中显式定义了notes.note,就很容易添加这个功能。
代码清单2-10 添加计算属性,将markdown格式转换为html格式
一旦成功实现了notes.convertfrommarkdowntohtml函数,接下来就可以在应用视图模板中将原先使用value的方式更改为使用新增的计算属性htmlvalue,这个改变显然易如反掌;简单更改视图handlebars模板(见代码清单2-2)的代码如下:
这样,记事本应用程序就改好了。接下来具体了解ember.js mvc模式下各层之间如何同步数据。