文档章节

Ember.js 入门指南——新建、更新、删除记录

ubuntuvim
 ubuntuvim
发布于 2015/10/21 02:05
字数 2146
阅读 693
收藏 2

前一篇介绍了查询方法,本篇介绍新建、更新、删除记录的方法。

本篇的示例代码创建在上一篇的基础上。对于整合firebase、创建routetemplate请参看上一篇,增加一个controllerember g controller articles

1,新建记录

       创建新的记录使用createRecord()方法。比如下面的代码新建了一个aritcle记录。修改模板,在模板上增加几个input输入框用于输入article信息。

<!--  app/templates/articles.hbs  -->
 
<div>
       <div>
              <div class="col-md-4 col-xs-4">
                     <ul>
                     {{#each model as |item|}}
                            <li>
                                   <!--设置路由,路由的层级与router.js里定义的要一致 -->
                  {{#link-to 'articles.article' item.id}}
                                          {{item.title}} -- <small>{{item.category}}</small>
                                   {{/link-to}}
                            </li>
                     {{/each}}
                     </ul>
 
 
                     <div>
                            title:{{input value=title}}<br>
                            body: {{textarea value=body cols="80" rows="3"}}<br>
                            category: {{input value=category}}<br>
                            <button {{ action "saveItem"}}>保存</button>
                            <font color='red'>{{tipInfo}}</font>
                     </div>
              </div>
 
              <div class="col-md-8 col-xs-8">
              {{outlet}}
              </div>
       </div>
</div>

       页面的字段分别对应这模型article的属性。点击保存后提交到controller处理。下面是获取数据保存数据的controller

//   app/controllers/articles.js
 
import Ember from 'ember';
 
export default Ember.Controller.extend({
 
       actions: {
 
              //  表单提交,保存数据到Store。Store会自动更新到firebase
              saveItem: function() {
                     var title = this.get('title');
                     if ('undefined' === typeof(title) || '' === title.trim()) {
                            this.set('tipInfo', "title不能为空");
                            return ;
                     }
 
                     var body = this.get('body');
                     if ('undefined' === typeof(body) || '' === body.trim()) {
                            this.set('tipInfo', "body不能为空");
                            return ;
                     }
                     var category = this.get('category');
                     if ('undefined' === typeof(category) || '' === category.trim()) {
                            this.set('tipInfo', "category不能为空");
                            return ;
                     }
 
                     //  创建数据记录
                     var article = this.store.createRecord('article', {
                            title: title,
                            body: body,
                            category: category,
                            timestamp: new Date().getTime()
                     });
                     article.save();  //保存数据的到Store
                     //  清空页面的input输入框
                     this.set('title', "");
                     this.set('body', "");
                     this.set('category', "");
              }
       }
});

       主要看createRecord方法,第一个参数是模型名称。第二个参数是个哈希,在哈希总设置模型属性值。最后调用article.save()方法把数据保存到Store,再由Store保存到firebase。运行效果如下图:

输入信息,点击保存后数据立刻会显示在列表”no form -- java”之后。然后你可以点击标题查询详细信息,body的信息会在页面后侧显示。

       通过这里实例我想你应该懂得去使用createRecord()方法了!

       但是如果有两个model是有关联关系保存的方法又是怎么样的呢?下面再新增一个model


ember g model users

然后在model中增加关联。

//   app/models/article.js
 
import DS from 'ember-data';
 
export default DS.Model.extend({
       title: DS.attr('string'),
       body: DS.attr('string'),
       timestamp: DS.attr('number'),
       category: DS.attr('string'),
       author: DS.belongsTo('user')  //关联user
});
//  app/models/user.js
 
import DS from 'ember-data';
 
export default DS.Model.extend({
     username: DS.attr('string'),
     timestamp: DS.attr('number'),
     articles: DS.hasMany('article')  //关联article
});

       修改模板articles.hbs在界面上增加录入作者信息字段。

……省略其他代码
<div>
       title:{{input value=title}}<br>
       body: {{textarea value=body cols="80" rows="3"}}<br>
       category: {{input value=category}}<br>
       <br>
       author: {{input value=username}}<br>
       <button {{ action "saveItem"}}>保存</button>
       <font color='red'>{{tipInfo}}</font>
</div>
……省略其他代码

       下面看看怎么在controller中设置这两个model的关联关系。一共有两种方式设置,一种是直接在createRecord()方法中设置,另一种是在方法外设置。

//   app/controllers/articles.js
 
import Ember from 'ember';
 
export default Ember.Controller.extend({
 
       actions: {
 
              //  表单提交,保存数据到Store。Store会自动更新到firebase
              saveItem: function() {
                     //  获取信息和校验代码省略……
 
                     // 创建user
                     var user = this.store.createRecord('user', {
                            username: username,
                            timestamp: new Date().getTime()
                     });
                     //  必须要执行这句代码,否则user数据不能保存到Store,
                     //  否则article通过user的id查找不到user
                     user.save();
 
                     //  创建article
                     var article = this.store.createRecord('article', {
                            title: title,
                            body: body,
                            category: category,
                            timestamp: new Date().getTime(),
                            author: user   //设置关联
                     });
 
                     article.save();  //保存数据的到Store
                     //  清空页面的input输入框
                     this.set('title', "");
                     this.set('body', "");
                     this.set('category', "");
                     this.set('username', "");
              }
       }
});

       界面如下图:

输入上如所示信息,点击保存可以在firebase的后台看到如下的数据关联关系。

注意点:与这两个数据的关联是通过数据的id维护的。

那么如果我要通过article获取user的信息要怎么获取呢?

       直接以面向对象的方式获取既可以。

{{#each model as |item|}}
       <li>
              <!--设置路由,路由的层级与router.js里定义的要一致 -->
         {{#link-to 'articles.article' item.id}}
                     {{item.title}} -- <small>{{item.category}}</small> -- <small>{{item.author.username}}</small>
              {{/link-to}}
       </li>
{{/each}}

       注意看助手{{ item.author.username }}。很像EL表达式吧!!

 

       前面提到过有两个方式设置两个model的关联关系。下面的代码是第二种方式:

//  其他代码省略……
//  创建article
var article = this.store.createRecord('article', {
       title: title,
       body: body,
       category: category,
       timestamp: new Date().getTime()
       // ,
       // author: user   //设置关联
});
 
// 第二种设置关联关系方法,在外部手动调用set方法设置
article.set('author', user);
//  其他代码省略……

       运行,重新录入信息,得到的结果是一致的。甚至你可以直接在createRecord方法里调用方法来设置两个model的关系。比如下面的代码段:

var store = this.store;  // 由于作用域问题,在createRecord方法内部不能使用this.store
var article = this.store.createRecord('article', {
       title: title,
       // ……
       // ,
       // author: store.findRecord('user', 1)   //设置关联
});
 
// 第二种设置关联关系方法,在外部手动调用set方法设置
article.set('author', store.findRecord('user', 1));

       这种方式可以直接动态根据userid属性值获取到记录,再设置关联关系。

       新增介绍完了,接着介绍记录的更新。

 

2,更新记录

       更新相对于新增来说非常相似。请看下面的代码段:

首先在模板上增加更新的设置代码,修改子模板articles/article.hbs

<!--  app/templates/articles/article.hbs  -->
 
<h1>{{model.title}}</h1>
<div>
{{model.body}}
</div>
 
<div>
<br><hr>
更新测试<br>
title: {{input value=model.title}}<br>
body:<br> {{textarea value=model.body cols="80" rows="3"}}<br>
<button {{action 'updateArticleById' model.id}}>更新文章信息</button>
</div>

 

增加一个controller,用户处理子模板提交的修改信息。

ember g controller articles/article

//  app/controllers/articles/article.js
 
import Ember from 'ember';
 
export default Ember.Controller.extend({
       actions: {
              // 根据文章id更新
              updateArticleById: function(params) {
                     var title = this.get('model.title');
                     var body = this.get('model.body');
                     this.store.findRecord('article', params).then(function(art) {
                            art.set('title', title);
                            art.set('body', body);
 
                            //  保存更新的值到Store
                            art.save();
                     });
              }
       }
});

       在左侧选择需要更新的数据,然后在右侧输入框中修改需要更新的数据,在修改过程中可以看到被修改的信息会立即反应到界面上,这个是因为Ember自动更新Store中的数据(还记得很久前讲过的观察者(observer)吗?)。

如果你没有点击更新文章信息提交,你修改的信息不会更新到firebase。页面刷新后还是原来样子,如果你点击了更新文章信息数据将会把更新的信息提交到firebase

 

       由于savefindRecord方法返回值是一个promises对象,所以你还可以针对出错情况进行处理。比如下面的代码:

var user = this.store.createRecord('user', {
       //  ……
});
user.save().then(function(fulfill) {
       //  保存成功
}).catch(function(error) {
       //  保存失败
});
 
this.store.findRecord('article', params).then(function(art) {
       //  ……
}).catch(function(error) {
       //  出错处理代码
});

具体代码我就不演示了,请读者自己编写测试吧!!

 

3,删除记录

       既然有了新增那么通常就会有删除。记录的删除与修改非常类似,也是首先查询出要删除的数据,然后执行删除。

//   app/controllers/articles.js
 
import Ember from 'ember';
 
export default Ember.Controller.extend({
 
       actions: {
 
              //  表单提交,保存数据到Store。Store会自动更新到firebase
              saveItem: function() {
                     // 省略
              },
              //  根据id属性值删除数据
              delById : function(params) {
 
                 //  任意获取一个作为判断表单输入值
               if (params && confirm("你确定要删除这条数据吗??")) {
                   //  执行删除
                   this.store.findRecord('article', params).then(function(art) {
                       art.destroyRecord();
                       alert('删除成功!');
                   }, function(error) {
                       alert('删除失败!');
                   });
               } else {
                   return;
               }
 
              }
       }
});

修改显示数据的模板,增加删除按钮,并传递数据的id值到controller

<!--  app/templates/articles.hbs  -->
 
<div>
       <div>
              <div class="col-md-4 col-xs-4">
                     <ul>
                     {{#each model as |item|}}
                            <li>
                                   <!--设置路由,路由的层级与router.js里定义的要一致 -->
                  {{#link-to 'articles.article' item.id}}
                                          {{item.title}} -- <small>{{item.category}}</small> -- <small>{{item.author.username}}</small>
                                   {{/link-to}}
                                   <button {{action 'delById' item.id}}>删除</button>
                            </li>
                     {{/each}}
                     </ul>
        // ……省略其他代码
       </div>
</div>

 

       结果如上图,点击第二条数据删除按钮。弹出提示窗口,点击确定之后成功删除数据,并弹出删除成功!,到firebase后台查看数据,确实已经删除成功。

然而与此关联的user却没有删除,正常情况下也应该是不删除关联的user数据的。

最终结果只剩下一条数据:


 

到此,有关新增、更新、删除的方法介绍完毕。已经给出了详细的演示实例,我相信,如果你也亲自在自己的项目中实践过,那么掌握这几个方法是很容易的!


© 著作权归作者所有

ubuntuvim

ubuntuvim

粉丝 33
博文 76
码字总数 98477
作品 1
深圳
后端工程师
私信 提问
加载中

评论(5)

-我已冷了眼
-我已冷了眼
谢谢 我在看一看吧
ubuntuvim
ubuntuvim 博主

引用来自“-我已冷了眼”的评论

我想问一下为什么我用this.store.findRecord('model',params) 报错:this.store.findRecord is not a function 在线急等

引用来自“ubuntuvim”的评论

是不是因为this作用域问题,或者你是不是在组件component中调用this.store.findRecord('model',params)?

引用来自“-我已冷了眼”的评论

我是刚学ember 很感谢你的 资料我用findAll 也可以实现了 但是我现在有个问题是我想用我看你那个模糊查询只要我在输入框输入他就会直接执行方法 但是我想给他加个事件 当我点击后再调用这个方法怎么做我试了试不行
你可以把post改成普通属性试试,计算属性都会自动检测变化并重新渲染模板的。你可以定义一个action,当点击按钮的时候再修改post的值。
-我已冷了眼
-我已冷了眼

引用来自“-我已冷了眼”的评论

我想问一下为什么我用this.store.findRecord('model',params) 报错:this.store.findRecord is not a function 在线急等

引用来自“ubuntuvim”的评论

是不是因为this作用域问题,或者你是不是在组件component中调用this.store.findRecord('model',params)?
我是刚学ember 很感谢你的 资料我用findAll 也可以实现了 但是我现在有个问题是我想用我看你那个模糊查询只要我在输入框输入他就会直接执行方法 但是我想给他加个事件 当我点击后再调用这个方法怎么做我试了试不行
ubuntuvim
ubuntuvim 博主

引用来自“-我已冷了眼”的评论

我想问一下为什么我用this.store.findRecord('model',params) 报错:this.store.findRecord is not a function 在线急等
是不是因为this作用域问题,或者你是不是在组件component中调用this.store.findRecord('model',params)?
-我已冷了眼
-我已冷了眼
我想问一下为什么我用this.store.findRecord('model',params) 报错:this.store.findRecord is not a function 在线急等
Ember.js 入门指南——总目录

Ember.js 是什么?我想对于想学习它的人应该知道它是个什么东西,如果你想了解那就赶紧去 Google 或者百度,本系列教程是通过学习官网教程然后摘抄个人觉得比较重要的部分,加上学习实例整合...

ubuntuvim
2015/10/25
1K
2
Ember.js 入门指南——model的关联关系处理

在前面《Ember.js 入门指南-模型定义》中介绍过模型之前的关系。主要包括一对一、一对多、多对多关系。但是还没介绍两个有关联关系model的更新、删除等操作。 为了测试新建两个model。 embe...

ubuntuvim
2015/10/21
346
0
Ember.js 入门指南--目录

本系列文章全部从(http://ibeginner.sinaapp.com/)迁移过来,欢迎访问原网站。 Ember.js 是什么?我想对于想学习它的人应该知道它是个什么东西,如果你想了解那就赶紧去 Google 或者百度,...

ubuntuvim
2015/09/07
396
2
Node.js开发入门——MongoDB与Mongoose

为了保存网站的用户数据和业务数据,通常需要一个数据库。MongoDB和Node.js特别般配,因为MongoDB是基于文档的非关系型数据库,文档是按BSON(JSON的轻量化二进制格式)存储的,增删改查等管...

foruok
2015/08/18
0
0
Ember.js 入门指南——模板渲染

路由的另一个重要职责是渲染同名字的模板。 比如下面的路由设置,posts路由渲染模板posts.hbs,路由new渲染模板posts/new.hbs。 Router.map(function() { this.route('posts', function() {...

ubuntuvim
2015/09/25
449
0

没有更多内容

加载失败,请刷新页面

加载更多

15、SpringMVC进行json交互

SpringMVC进行json交互 json数据格式在接口调用中、html页面中较常用,json格式比较简单,解析还比较方便。 请求json、输出json。要求请求的是json串,前端页面中需要将请求的内容转成json,...

快乐的瓶子
29分钟前
7
0
delphi版插apc杀进程驱动源码

从c代码转的,备份一下,里面有硬编码unit MyDriver;{$HINTS OFF}{$WARNINGS OFF}interfaceusesnt_status, ntoskrnl, native, winioctl, fcall, macros;typeTKILL = ...

simpower
33分钟前
4
0
带你上手一款下载超 10 万次的 IDEA 插件

作者 | 倪超(银时) 阿里云开发者工具产品专家 本文整理自 11 月 7 日社群分享,每月 2 场高质量分享,点击加入社群。 导读:Cloud Toolkit 是本地 IDE 插件,帮助开发者更高效地开发、测试...

阿里云官方博客
34分钟前
4
0
GMAT语法7个常考重要考点分析

GMAT语法考点多,并非所有考点都值得重点关注。实际上GMAT语法存在一些高频考点,考生需要优先掌握它们才能更好地保证得分。同时GMAT备考中大家还需要培养连续做题的耐力。下面小编就来做具体...

bole6
38分钟前
4
0
最佳实践 | RDS & POLARDB归档到X-Pack Spark计算

X-Pack Spark服务通过外部计算资源的方式,为Redis、Cassandra、MongoDB、HBase、RDS存储服务提供复杂分析、流式处理及入库、机器学习的能力,从而更好的解决用户数据处理相关场景问题。 RD...

一肥仔
40分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部