Ember.js 入门指南 (二)
来源:互联网 发布:photoshop软件破解版 编辑:程序博客网 时间:2024/05/18 02:25
@(Ember)[MVVM|前端框架|HTML桌面应用]
序言
经常有人质疑,在前端搞MV*有什么意义?也有人跟我提出这样的疑问:以AngularJS,Knockout,BackBone为代表的MV*框架,它跟jQuery有什么区别?我jQuery用得好好的,有什么必要再引入这种框架?
其实,不管我们使用的是一个类库还是一个框架,都不应该忘记我们最终目的,或许你正在为一个项目做技术选型,或许你正在为你的应用考虑代码重构,又或许你只是单纯的想做一些学术性研究,所以框架和类库的选择没有绝对只有最适合。
以jQuery为代表,针对界面上常见的DOM操作,远程请求,数据处理等作了封装,也有专注于处理数据的Underscore,而今天的主角Ember.js正是一款为构建富HTML桌面应用的理想框架。
EMBER对象模型
Ember增强了简单的JavaScript对象模型,使之能够支持绑定和观察者,同时也支持一种更加强大的、基于混合的(mixin-based)代码共享途径。
作为最基本的形式,你可以使用Ember.Object
的extend
方法创建一个新的Ember类。
Person = Ember.Object.extend({ say: function(thing) { alert(thing); }});
一旦你成功创建了一个新类,就可以使用create来创建类的实例了。类中定义的任何属性在实例中都是可用的。
var person = Person.create();person.say("Hello") // alerts "Hello"
创建实例时,也可以通过传入对象来为实例增添额外的属性。
var tom = Person.create({ name: "Tom Dale", helloWorld: function() { this.say("Hi my name is " + this.get('name')); }});tom.helloWorld() // alerts "Hi my name is Tom Dale"
由于Ember支持绑定和观察者,因此你可以随时通过get方法访问属性,也可以通过set方法设置属性。
当创建一个对象的新的实例时,也可以覆写类中定义的任何属性和方法。在本例中,作为例子,你可以覆写从Person
类继承的say
方法。
var yehuda = Person.create({ name: "Yehuda Katz", say: function(thing) { var name = this.get('name'); this._super(name + " says: " + thing); }});
你可以使用对象的_super
方法(super是JavaScript中的保留字)来调用被你覆写的原始方法。
类的子类
你也可以使用extend方法为类创建子类。事实上,我们上面使用Ember.Object对象的extend方法创建新类时,即是创建了Ember.Object的子类。
var LoudPerson = Person.extend({ say: function(thing) { this._super(thing.toUpperCase()); }});
当创建子类时,你可以使用this._super
来调用被你覆写的方法。
重新打开类和实例
无需一次性将类定义完全,你可以使用reopen
方法来重新打开(reopen)一个类并为其定义新的属性。
当使用reopen
时,你也同样可以覆写已经存在的方法并调用this._super
。
Person.reopen({ // override `say` to add an ! at the end say: function(thing) { this._super(thing + "!"); }});
正如你所见,reopen
是用来为实例添加属性和方法的。而当你需要创建类的方法或为类本身添加属性时,则可使用reopenClass
。
Person.reopenClass({ createMan: function() { return Person.create({isMan: true}) }});Person.createMan().get('isMan') // true
计算属性 (Getters)
你可能经常需要一个基于其他属性计算而来的属性。Ember的对象模型可以使你很轻松地在常规的类定义中定义计算属性。
Person = Ember.Object.extend({ // these will be supplied by `create` firstName: null, lastName: null, fullName: function() { var firstName = this.get('firstName'); var lastName = this.get('lastName'); return firstName + ' ' + lastName; }.property('firstName', 'lastName')});var tom = Person.create({ firstName: "Tom", lastName: "Dale"});tom.get('fullName') // "Tom Dale"
当为类创建子类或者新的实例时,你可以覆写任何计算属性。
计算属性 (Setters)
你也可以定义当设置计算属性时Ember所执行的动作。当你尝试设置计算属性时,可以使用对应的名-值(key and value)对其进行设置。
Person = Ember.Object.extend({ // these will be supplied by `create` firstName: null, lastName: null, fullName: function(key, value) { // getter if (arguments.length === 1) { var firstName = this.get('firstName'); var lastName = this.get('lastName'); return firstName + ' ' + lastName; // setter } else { var name = value.split(" "); this.set('firstName', name[0]); this.set('lastName', name[1]); return value; } }.property('firstName', 'lastName')});var person = Person.create();person.set('fullName', "Peter Wagenet");person.get('firstName') // Peterperson.get('lastName') // Wagenet
对于setter和getter,Ember都会调用计算属性,你可以通过检查参数的个数来确定该计算属性究竟是被getter还是setter调用的。
观察者
Ember支持观察任何属性,包括计算属性。你可以使用addObserver
方法在某个对象上设置观察者。
Person = Ember.Object.extend({ // these will be supplied by `create` firstName: null, lastName: null, fullName: function() { var firstName = this.get('firstName'); var lastName = this.get('lastName'); return firstName + ' ' + lastName; }.property('firstName', 'lastName')});var person = Person.create({ firstName: "Yehuda", lastName: "Katz"});person.addObserver('fullName', function() { // deal with the change});person.set('firstName', "Brohuda"); // observer will fire
由于fullName
这个计算属性依赖于firstName
,所以更新firstName
也会触发fullName
上的观察者。
由于观察者的应用非常普遍,Ember提供了一种能够在类定义的内部定义观察者的方式。
Person.reopen({ fullNameChanged: function() { // this is an inline version of .addObserver }.observes('fullName')});
绑定
绑定在两个属性之间创建了一个连接,这样一个属性改变时另一个也可以随之自动更新到最新的值。绑定也可以连接同一对象内的属性,或者跨越两个不同的对象。与其他大部分框架所包含的绑定实现不同的是,Ember.js的绑定可以用在任何对象上,而不仅仅用在视图和模型之间。
最简单的创建双向绑定的方法是,创建一个以Binding
字串结尾的属性,然后指定一个相对于全局作用域(global scope)的路径:
App.wife = Ember.Object.create({ householdIncome: 80000});App.husband = Ember.Object.create({ householdIncomeBinding: 'App.wife.householdIncome'});App.husband.get('householdIncome'); // 80000// Someone gets raise.App.husband.set('householdIncome', 90000);App.wife.get('householdIncome'); // 90000
注意这个绑定不会立即更新,Ember会等待应用的所有代码运行完成之后再同步变更,因此你可以随意改变某个绑定的属性,而不用担心同步这些临时值所耗费的开销。
单向绑定
单向绑定只将变更单向传播。通常,单向绑定只是为了性能优化,你可以放心地使用更加简洁的双向绑定语法(当然,如果你总是只改变一边的话,那么双向绑定事实上也是单向绑定了)。
App.user = Ember.Object.create({ fullName: "Kara Gates"});App.userView = Ember.View.create({ userNameBinding: Ember.Binding.oneWay('App.user.fullName')});// Changing the name of the user object changes// the value on the view.App.user.set('fullName', "Krang Gates");// App.userView.userName will become "Krang Gates"// ...but changes to the view don't make it back to// the object.App.userView.set('userName', "Truckasaurus Gates");App.user.get('fullName'); // "Krang Gates"
应用程序 APPLICATION
根据你的需求,有几种方式可以创建你的第一个Ember App.
如果你的需求较简单或者只是感兴趣随便玩玩,你可以下载Ember.js入门套件(Starter Kit),该入门套件基于HTML5 样板,无需任何构建工具、没有其他依赖。你也可以使用一些其他前端Scaffold工具来构建你的ember应用(例如: Yoeman )。当然你也可以根据自己的项目特点来构建自己的应用。
创建一个应用程序
每个Ember app
都应该有一个Ember.Application
的实例。这个对象将会作为你的app中所有类和实例的全局可访问的命名空间(globally-accessible namespace)
。此外,它也在页面上设置了事件监听器,确保当用户与你的用户界面进行交互时你的视图可以接收到事件。
创建Ember.js应用程序的第一步是创建一个Ember.Application
类的实例化对象:
window.App = Ember.Application.create();
这里将实例化的对象命名为App,开发者可以根据应用程序的用途,选择意义相符的名字。
创建一个应用程序的实例对象非常重要,原因如下:
定义应用程序的命名空间,所有类都定义成该对象的属性(比如App.PostsView、App.PostsController)。这样做可以避免污染全局作用域。
在document上增加事件监听,并负责将事件发送给视图。
自动渲染模板,包括根模板,以及其他放入根模板的模板,都将被渲染。
基于当前URL创建路由器并开始路由。
Person.reopenClass({ createMan: function() { return Person.create({isMan: true}) }});Person.createMan().get('isMan') // true
你可以随意为你的命名空间命名,不过必须以大写字母开头,这样绑定才能找到它。
如果要将Ember应用嵌入到某个现存的网站中,可以通过提供rootElement属性来将某个特定的元素作为事件监听器。
小结:
使用计算属性创建由其他属性综合决定的新属性。
计算属性不应该包含应用的行为,而且当调用时不应有任何附加影响。
除非在极少数情况下,多次调用相同的计算属性应该总是返回同样的值(当然,除了属性所依赖的属性值改变的情况。)
观察者应该包含反映其他属性变化的行为。
当你需要在绑定完成同步之后执行一些行为的时候,观察者会非常有用。
绑定通常用在确保位于不同层的对象总能保持同步。
例如,你使用
Handlebars
绑定了你的视图和控制器,你也可能经常需要绑定同一层的两个对象。例如,你可能有个
App.selectedContactController
需要绑定在App.contactsController
的selectedContact
属性上
- Ember.js 入门指南 (二)
- Ember.js 入门指南 (一)
- Ember.js 入门指南——扩展(reopen)
- Ember.js 入门指南——观察者(observer)
- Ember.js 入门指南——绑定(bingding)
- Ember.js 入门指南——枚举(enumerables)
- Ember.js 入门指南——控制器(controller)
- Ember.js 入门指南——目录
- Ember.js 入门指南——计算属性(compute properties)
- Ember.js 入门指南——handlebars基础
- Ember.js 入门指南——handlebars条件表达式
- Ember.js 入门指南——handlebars遍历标签
- Ember.js 入门指南——handlebars属性绑定
- Ember.js 入门指南——{{link-to}} 助手
- Ember.js 入门指南——{{action}} 助手
- Ember.js 入门指南——表单元素
- Ember.js 入门指南——调试助手
- Ember.js 入门指南——工具类的助手
- java设计模式学习(二)策略模式
- Linux环境变量操作
- UML基础(终极总结)
- spring(基础五) spring实现后台的任务调度TimerTask和Quartz
- 12、Integer to Roman
- Ember.js 入门指南 (二)
- iOS 序列化与反序列化
- VS 项目中添加 include、lib 库文件
- 第二天:poj1002(虽然完成了题目但是时间太久了。。。加油坚持下去)
- DesignPattern
- spring测试套件
- spring jmx客户端 和服务端配置
- ioS 证书相关 (二)
- hadoop2.6配置过程