emberjs

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.1

它会在当前目录下建一个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文件,代码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

<!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

标签: mvvmemberjsjs框架mvcbower

时间: 2024-10-09 22:28:38

emberjs的相关文章

知识分享---EmberJs系列文章

JS前端框架之Ember.js系列文章 本文为文章索引,主要是罗列Ember.js的相关文章便于阅读. 基础篇 1. EmberJs之What|Why|HoW 进阶篇 高级篇

Emberjs之ComputedProperty

Computed Property (简称CP) 1. What is CP? In a nutshell, computed properties let you declare functions as properties. You create one by defining a computed property as a function, which Ember will automatically call when you ask for the property. You c

EmberJs之3W

写在前面 最近比较忙,换了新工作还要学习很多全新的技术栈,并给自己找了很多借口来不去坚持写博客.常常具有讽刺意味的是,更多剩下的时间并没有利用而更多的是白白浪费,也许这就是青春吧,挥霍吧,这不是我想要的,既然这样,我还要继续写下去,坚持把博客做好,争取进前100博客,在此谨记. 2015年5月7日深夜,于电脑旁. 文章索引 JS前端框架之Ember.js系列 What is EmberJs? 现如今Js框架层出不穷,各自独领风骚.你争我夺,还有各种新鲜框架来抢占市场吸引眼球,那究竟我们该如何选择

emberjs学习二(ember-data和localstorage_adapter)

emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用bower install安装这两个插件.如下 "dependencies": { "jquery": "~1.9.1", "ember": "~1.13.10", "handlebars"

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

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.love

Emberjs 上手 - 使用Grunt进行项目组织与创建

在要开始构建Emberjs的应用前,首先考虑一个可以组织和管理好整个JavaScript项目的方法和工具,可以使用Ember-cli,也可以使用通用的JavaScript的构建工具Grunt. 为什么需要这样的工具呢?原因是软件项目的开发与管理离不开良好的代码组织方法与管理工具的使用,特别是团队开发人员多,项目结构复杂时,技术的组织管理就会是一个挑战.好比盖一幢楼房,如果不能够有效地管理建筑材料.工人与施工进度时,那么工程质量与交付就无法得到保障了. Grunt 的功能 好了,现在来看看使用Gr

EmberJs之数组绑定@each&amp;[]

写在前面 好长时间没有写博客了,昨天花了些时间又整理了下之前发布过的<Ember.js之computed Property>文章,并创建了一个测试代码库,花了些时间,希望能使用测试代码的方式,来演示如何使用Ember.js同时能避免升级Ember版本后,一些功能上的变化所带来的隐含Bug. 如果大家对Ember.js有兴趣想一起研究的话,欢迎大家一起维护测试代码库  :) 本文主要是针对Ember.Array中的[]和@each,数组方法进行详细分析. 文章索引 JS前端框架之Ember.js

Emberjs 分页

<!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <!-- Created using JS Bin http://jsbin.com Copyright (c) 2015 by machty (http://jsbin.com/ucanam/4075/edit) Released under the MIT license: http://jsbin.mit-license.org -->

三大JavaScript框架对比——AngularJS、BackboneJS和EmberJS

<三大JavaScript框架对比--AngularJS.BackboneJS和EmberJS> 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 如果有心搜索的话,你能找出上百种JavaScript框架.当我们要开发一个现代化的.敏捷酷炫的网站时,JavaScript是必备的基础技术.那么问题来了,如何在这么多JavaScript框架中选取最能满足我们需求的框架?这是一个难题.而且还有很多挑战,比如要让网站在不同的客户端浏览器上表现出一致的行为和外