code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent;
}

code, pre tt {
background-color: transparent;
border: none;
}
-->

初学emberjs

博客:http://www.cnblogs.com/xiangbing/p/emberjs-test.html

案例:http://www.lovewebgames.com/emberjs/test/index.html

源码:https://github.com/tianxiangbing/emberjs-test

准备工作

首页我们要做的是从网上下载下来emberjs相关的文件,目前在1.x的版本中,ember是要依赖jquery(v1.7.1~2.2.0) 和handlebars(v1.x)的,有一个比较好的方式来得到这些资源,那就是用bower.bower的安装很简单:

npm install -g bower   

装完bower就可以使用bower来下载资源了,比如我们要下载jquery 1.9.1版本的,我们可以这样写

bower install jquery#1.9.

它会在当前目录下建一个bower_components的目录,把jquery的文件下载到jquery文件目录下.我们也可以把git上的项目发布到bower上,然后再从bower安装到本地,具体方法可以看这里http://blog.fens.me/nodejs-bower-intro/

我的案例已经发布在bower上,你可以直接用以下命令获取

bower install emberjs-test

点开bower_components下的test1目录,执行

npm install

安装grunt-watch,方便开发

再下载ember相关的资源

bower.json:

"dependencies": {
"jquery": "~1.9.1",
"ember": "~1.13.10",
"handlebars":"~1.3.0",
"ember-data":"~1.13.11"
}

执行 bower install 查看资源列表 bower list如图所示

开始一个例子

然后我们要根据这些文件做一个简单的例子,我们新建一个html页面index.html,引用js文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>emberjs 初学记要</title>
<script type="text/javascript" src="http://localhost:9090/livereload.js"></script>
</head>
<body>
<script type="text/javascript" src="bower_components/jquery/jquery.min.js"></script>
<script type="text/javascript" src="bower_components/handlebars/handlebars.min.js"></script>
<script type="text/javascript" src="bower_components/ember/ember.min.js"></script>
</body>
</html> 

这里看到我在head里多引入了一个livereload.js,这个文件是使用grunt watch时生成的,可以动态的改变页面,你可以使用chrome的插件livereload.

好了,准备工作做好了之后 ,我们就可以编写首页的模板了,在页面添加如下代码:

<script type="text/x-handlebars">
首页
</script>

然后新建一个js文件,这里命名为app.js,放在js目录下,引入.

window.App = Ember.Application.create();

这时会发现页面上什么都没有,然后在console里还报了一个错:

Uncaught Error: Cannot call `compile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compile`.

这个错误的大致意思好像是说我没有ember-template-compiler.js文件,但奇了怪的是,所以解析模板时出错了;但是在更早期的版本里是不需要的,可能是后期为了移除handlebars所以独立出来了吧,在bower_components/ember中还真有这么个文件,好吧,引入它.

<script type="text/javascript" src="bower_components/jquery/jquery.min.js"></script>
<script type="text/javascript" src="bower_components/handlebars/handlebars.min.js"></script>
<script type="text/javascript" src="bower_components/ember/ember-template-compiler.js"></script>
<script type="text/javascript" src="bower_components/ember/ember.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>

好了,页面终于出现内容了,然后我们在模板中加入outlet,这是一个其他模块的入口,然后我们在app.js中加入其他的模块路由.

App.Router.map(function(){
this.resource('add',{path:'add'});
});

这里可以使用resource也可以直接用route

this.route('add')

据说它们间的区别就是resource可以有子路由,但route已经是最小的路由了,所以可以理解为,大的类目时用recource,终极时用route,你开心就好。 然后我们添加add的模板,这里add的模板id要和link-to的参数一致,并且跟resource或route的第一个参数一样,path参数指的是url里的hash值.

<script type="text/x-handlebars" id="add">
<table>
<tr>
<td>标题</td>
<td><input type="text" /></td>
</tr>
<tr>
<td>内容</td>
<td><textarea></textarea></td>
</tr>
<tr>
<td></td>
<td><input type="button" value="确认"></td>
</tr>
</table>
</script>

这里有一个操作,所以应该有个Controller,我们先在app.js里加上这个controller.

App.AddController=Ember.Controller.extend({
actions:{
new:function(){
console.log('new')
var title = $('#title').val();
var content = $('#content').val();
//do save
}
}
});

它的命名规则是单词首字母大写,然后ember会把它注册到add这个模块里,这样你就可以在add模板中使用这个控制器了。把按钮改掉

<input type="button" value="确认" {{action "new"}}>

由于我们现在还没有使用localStorage这类本地存储,所以我们可以使用变量来临时的保存一下,但实际的应用中,似乎更多的是与服务器的交互。 它义数组var data=[];然后再action/new下加入

data.push({title:title,content:content});
this.transitionToRoute('index');

transitionToRoute的意思就是转到另一个路由去。我们这里转到首页去,然后我们看到一片空白的首页,还不知道是什么情况,因为还没有写代码让刚才加入的记录显示出来,好,我们在首页的模板中把记录each出来.

<script type="text/x-handlebars" id="index">
<ol>
{{#each model}}
<li>{{title}}</li>
{{/each}}
</ol>
</script>

这里each的是model,如果直接each .会导致不更新。然后我们添加一个IndexRoute来返回一个数据集.

App.IndexRoute = Ember.Route.extend({
model: function() {
return data
}
});

这里的IndexRoute就会默认在路由到index首页时调用。

我们在添加一个查看的按钮查看详情,为了能找到当前记录,我们给每条记录加一个index属性记录当前索引:

data.push({
title: title,
content: content,
index:data.length
});
<li>{{title}}{{#link-to "info" this}}查看{{/link-to}}</li>

不知道为什么在这里不能直接取@index索引,所以只能我们在每条记录里加个唯一值。然后在路由中加上resouce

this.resource('index', {
path: '/'
}, function() {
this.resource('info', {
path: 'info/:index'
})
})

这里我们把info的路由放在了index的下面,这样,就可以达到index和info同时存在了。这里要在index的模板中加上一个{{outlet}}才行。

{{model.title}}

{{model.content}}

同样的情况出现了,我要加上model才行,不明白的为什么{{title}}可以取出来content一定要{{model.content}}才行。在InfoRoute中返回当前的数组值

App.InfoRoute = Ember.Route.extend({
model: function(param) {
console.log(data[param.index].content)
return data[param.index]
}
});

在详情模板中加入编辑按钮,我们根据一个值来判断是显示“编辑”还是“保存”.

<div style="float:left;">
<h1>{{model.title}}</h1>
<p>
{{model.content}}
</p>
{{#if isEditing}}
<button {{action "save"}}>保存</button>
{{else}}
<button {{action "edit"}}>编辑</button>
{{/if}}
</div>

这里的isEditing是在Controlleraction中新增的一个属性,在actions中新增save和edit方法

App.InfoController = Ember.ObjectController.extend({
actions: {
isEditing: false,
edit: function() {
this.set('isEditing',true);
},
save:function(){
this.set('isEditing',false);
}
}
});

这里的值都要使用set方法来改变,否则不会导致页面的刷新模板.然后我们加入一个子模板来显示编辑的内容。

<script type="text/x-handlebars" id="post/edit">
<table>
<tr>
<td>标题</td>
<td>{{input type="text" value=title}}</td>
</tr>
<tr>
<td>内容</td>
<td>{{textarea value=model.content}}</td>
</tr>
<tr>
<td></td>
<td><input type="button" value="确认" {{action "save"}}></td>
</tr>
</table>
</script>

这里用的是{{input}}方式的控件,这样就可以实现传说中的双向绑定了,它是基于Ember.TextField类的,所以也是可以自定义一个Input控件的。如下官方例子所示input api:

Todos.EditTodoView = Ember.TextField.extend({
didInsertElement: function() {
this.$().focus();
}
});
Ember.Handlebars.helper('edit-todo', Todos.EditTodoView);

然后就莫名其妙地完成了保存操作,好吧,我以为我还要save一下,官方的例子是使用的model,所以要对先this.get('model).save()一下才会有用。

最后我们要做的就是删除了,先加一个action为del的链接按钮:

{{#each model}}
<li>{{title}}{{#link-to "info" this}}查看{{/link-to}} <a href="javascript:void(0)" {{action "del" index}}>删除</a></li>
{{/each}}

然后在IndexController中新增del的action

App.IndexController = Ember.ArrayController.extend({
actions: {
del: function(index) {
var d = this.get('model');
console.log(d)
var obj = d.findBy('index',index)
d.removeObject(obj)
}
}
});

这里的问题是,我们要对model进行操作,才能实时的反应到页面上,看了下model的方法,可以使用findBy找出该元素,再进行removeObject

最终,我们就完成了一整个的增删改操作了。因为我也是在学习过程中,如果有什么不对的地方,请指出纠正吧!也欢迎加入我的Q群77813547

emberjs初学记要的更多相关文章

  1. emberjs学习一(环境和第一个例子)

    code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent; } code, pre t ...

  2. emberjs学习二(ember-data和localstorage_adapter)

    emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...

  3. DDD初学指南

    去年就打算总结一下,结果新换的工作特别忙,就迟迟没有认真动手.主要内容是很多初学DDD甚至于学习很长时间的同学没有弄明白DDD是什么,适合什么情况.这世界上没有银弹,抛开了适合的场景孤立的去研究DDD ...

  4. gulp初学

    原文地址:gulp初学 至于gulp与grunt的区别,用过的人都略知一二,总的来说就是2点: 1.gulp的gulpfile.js  配置简单而且更容易阅读和维护.之所以如此,是因为它们的工作方式不 ...

  5. 初学seaJs模块化开发,利用grunt打包,减少http请求

    原文地址:初学seaJs模块化开发,利用grunt打包,减少http请求 未压缩合并的演示地址:demo2 学习seaJs的模块化开发,适合对seajs基础有所了解的同学看,目录结构 js — —di ...

  6. 初学Vue2.0--基础篇

    概述: 鉴于本人初学,使用的编译器是webStorm,需添加对VUE的支持,添加方法可以参考 http://www.jianshu.com/p/142dae4f8b51. 起步: 1. 扎实的 Jav ...

  7. 初学Python

    初学Python 1.Python初识 life is short you need python--龟叔名言 Python是一种简洁优美语法接近自然语言的一种全栈开发语言,由"龟叔&quo ...

  8. Javascript初学篇章_5(对象)

    对象 Javascript是一种面向对象的语言,因此可以使用面向对象的思想来进行javascript程序设计对象就是由一些彼此相关的属性和方法集合在一起而构成的一个数据实体.举个例子,一只猫是个对象, ...

  9. 初学Objective-C语言需要了解的星星点点

             其实大多数开发初学者都有一些相同的特点,可以说是一种“职业病”.Most有其他平台开发基础的初学者,看到Xcode就想摩拳擦掌:看到Interface Builder就想跃跃欲试:而 ...

随机推荐

  1. [LeetCode] Best Meeting Point

    Problem Description: A group of two or more people wants to meet and minimize the total travel dista ...

  2. [Z]The Boost C++ Libraries

    看起来是个学习boost非常不错的材料,应该是boost的官方教程之类: http://theboostcpplibraries.com/

  3. 一个方法告诉你as3的removeChild性能有多烂

    其实as3这个坑我早就踩过,不过那时没太注意,最近把项目的removeChild干掉换成了visible=false,发现效率质的提升…… 先贴一下代码吧 private function testR ...

  4. JDK的下载、安装及环境变量的配置

    官网下载JDK: www.oracle.com 或者 www.java.sun.com   安装JDK: 双击运行下载的 jdk-8u25-windows-i586.exe即可. 假设安装目录为:D: ...

  5. Android 使用版本控制工具时添加忽略文件方式

    一.使用SVN管理项目时,添加忽略文件的方式 Android Studio 配合SVN时,添加忽略文件相对简单,首先打开项目的Settings选项,切换到Version Control下的Ignore ...

  6. Visual Studio .NET项目转换器(ProjectConverter)修改

    Visual Studio .NET 项目转换器非常类似于ASP.NET版本转换器,区别在于它用于转换 Visual Studio 项目文件的版本.尽管在 .NET 框架的 1.0 版和 1.1 版之 ...

  7. MFC ADO连接Oracle12c数据库 客户端环境搭建

    ADO连接方式一:Provider=MSDAORA.1; 环境配置如下: 去官网下载ODAC121024Xcopy_32bit.zip安装 安装方式如下: (1)解压文件 (2)用命令行CD到该文件的 ...

  8. 重写js alert

    Window.prototype.alert = function(){ //创建一个大盒子 var box = document.createElement("div"); // ...

  9. google翻译,翻译当前的网页

    网页翻译为德语(Translate Page To German) <a href="javascript: void(window.open('http://translate.go ...

  10. [Math] Deferred Acceptance Algorithm

    约会配对问题 一.立即接受算法: 对于约会的配对,大家都去追自己最心仪的女生.而这个女生面对几位追求者,要立刻做个决定. 被拒绝的男生们调整一下心情,再去追求心中的 No. 2.以此类推. 这样做法有 ...