Ember 新建、更新、删除记录

2018-01-06 18:00 更新

前一篇介绍了查询方法,本篇介绍新建、更新、删除记录的方法。 本篇的示例代码创建在上一篇的基础上。对于整合firebase、创建routetemplate请参看上一篇,增加一个controller:ember g controller articles

1,新建记录

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

  1. <div class="container">
  2. <div class="row">
  3. <div class="col-md-4 col-xs-4">
  4. <ul class="list-group">
  5. {{#each model as |item|}}
  6. <li class="list-group-item">
  7. {{#link-to 'articles.article' item.id}}
  8. {{item.title}} -- <small>{{item.category}}</small>
  9. {{/link-to}}
  10. </li>
  11. {{/each}}
  12. </ul>
  13. <div>
  14. title:{{input value=title}}<br>
  15. body: {{textarea value=body cols="80" rows="3"}}<br>
  16. category: {{input value=category}}<br>
  17. <button {{ action "saveItem"}}>保存</button>
  18. <font color='red'>{{tipInfo}}</font>
  19. </div>
  20. </div>
  21. <div class="col-md-8 col-xs-8">
  22. {{outlet}}
  23. </div>
  24. </div>
  25. </div>

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

  1. // app/controllers/articles.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. // 表单提交,保存数据到Store。Store会自动更新到firebase
  6. saveItem: function() {
  7. var title = this.get('title');
  8. if ('undefined' === typeof(title) || '' === title.trim()) {
  9. this.set('tipInfo', "title不能为空");
  10. return ;
  11. }
  12. var body = this.get('body');
  13. if ('undefined' === typeof(body) || '' === body.trim()) {
  14. this.set('tipInfo', "body不能为空");
  15. return ;
  16. }
  17. var category = this.get('category');
  18. if ('undefined' === typeof(category) || '' === category.trim()) {
  19. this.set('tipInfo', "category不能为空");
  20. return ;
  21. }
  22. // 创建数据记录
  23. var article = this.store.createRecord('article', {
  24. title: title,
  25. body: body,
  26. category: category,
  27. timestamp: new Date().getTime()
  28. });
  29. article.save(); //保存数据的到Store
  30. // 清空页面的input输入框
  31. this.set('title', "");
  32. this.set('body', "");
  33. this.set('category', "");
  34. }
  35. }
  36. });

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

结果截图

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

通过这里实例我想你应该懂得去使用createRecord()方法了!但是如果有两个模型是有关联关系保存的方法又是怎么样的呢?下面再新增一个模型。

  1. ember g model users

然后在模型中增加关联。

  1. // app/models/article.js
  2. import DS from 'ember-data';
  3. export default DS.Model.extend({
  4. title: DS.attr('string'),
  5. body: DS.attr('string'),
  6. timestamp: DS.attr('number'),
  7. category: DS.attr('string'),
  8. author: DS.belongsTo('user') //关联user
  9. });
  10. // app/models/user.js
  11. import DS from 'ember-data';
  12. export default DS.Model.extend({
  13. username: DS.attr('string'),
  14. timestamp: DS.attr('number'),
  15. articles: DS.hasMany('article') //关联article
  16. });

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

  1. ……省略其他代码
  2. <div>
  3. title:{{input value=title}}<br>
  4. body: {{textarea value=body cols="80" rows="3"}}<br>
  5. category: {{input value=category}}<br>
  6. <br>
  7. author: {{input value=username}}<br>
  8. <button {{ action "saveItem"}}>保存</button>
  9. <font color='red'>{{tipInfo}}</font>
  10. </div>
  11. ……省略其他代码

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

  1. // app/controllers/articles.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. // 表单提交,保存数据到Store。Store会自动更新到firebase
  6. saveItem: function() {
  7. // 获取信息和校验代码省略……
  8. // 创建user
  9. var user = this.store.createRecord('user', {
  10. username: username,
  11. timestamp: new Date().getTime()
  12. });
  13. // 必须要执行这句代码,否则user数据不能保存到Store,
  14. // 否则article通过user的id查找不到user
  15. user.save();
  16. // 创建article
  17. var article = this.store.createRecord('article', {
  18. title: title,
  19. body: body,
  20. category: category,
  21. timestamp: new Date().getTime(),
  22. author: user //设置关联
  23. });
  24. article.save(); //保存数据的到Store
  25. // 清空页面的input输入框
  26. this.set('title', "");
  27. this.set('body', "");
  28. this.set('category', "");
  29. this.set('username', "");
  30. }
  31. }
  32. });

界面截图

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

firebase数据截图

注意点:与这两个数据的关联是通过数据的id维护的。 那么如果我要通过article获取user的信息要怎么获取呢?

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

  1. {{#each model as |item|}}
  2. <li class="list-group-item">
  3. {{#link-to 'articles.article' item.id}}
  4. {{item.title}} -- <small>{{item.category}}</small> -- <small>{{item.author.username}}</small>
  5. {{/link-to}}
  6. </li>
  7. {{/each}}

注意看助手{{ item.author.username }}。很像EL表达式吧!! 前面提到过有两个方式设置两个模型的关联关系。下面的代码是第二种方式:

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

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

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

这种方式可以直接动态根据user的id属性值获取到记录,再设置关联关系。新增介绍完了,接着介绍记录的更新。

2,更新记录

更新相对于新增来说非常相似。请看下面的代码段: 首先在模板上增加更新的设置代码,修改子模板articles/article.hbs

  1. <h2>{{model.title}}</h2>
  2. <div class = "body">
  3. {{model.body}}
  4. </div>
  5. <div>
  6. <br><hr>
  7. 更新测试<br>
  8. title: {{input value=model.title}}<br>
  9. body:<br> {{textarea value=model.body cols="80" rows="3"}}<br>
  10. <button {{action 'updateArticleById' model.id}}>更新文章信息</button>
  11. </div>

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

  1. ember g controller articles/article
  1. // app/controllers/articles/article.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. // 根据文章id更新
  6. updateArticleById: function(params) {
  7. var title = this.get('model.title');
  8. var body = this.get('model.body');
  9. this.store.findRecord('article', params).then(function(art) {
  10. art.set('title', title);
  11. art.set('body', body);
  12. // 保存更新的值到Store
  13. art.save();
  14. });
  15. }
  16. }
  17. });

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

结果截图

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

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

  1. var user = this.store.createRecord('user', {
  2. // ……
  3. });
  4. user.save().then(function(fulfill) {
  5. // 保存成功
  6. }).catch(function(error) {
  7. // 保存失败
  8. });
  9. this.store.findRecord('article', params).then(function(art) {
  10. // ……
  11. }).catch(function(error) {
  12. // 出错处理代码
  13. });

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

3,删除记录

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

  1. // app/controllers/articles.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. // 表单提交,保存数据到Store。Store会自动更新到firebase
  6. saveItem: function() {
  7. // 省略
  8. },
  9. // 根据id属性值删除数据
  10. delById : function(params) {
  11. // 任意获取一个作为判断表单输入值
  12. if (params && confirm("你确定要删除这条数据吗??")) {
  13. // 执行删除
  14. this.store.findRecord('article', params).then(function(art) {
  15. art.destroyRecord();
  16. alert('删除成功!');
  17. }, function(error) {
  18. alert('删除失败!');
  19. });
  20. } else {
  21. return;
  22. }
  23. }
  24. }
  25. });

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

  1. <div class="container">
  2. <div class="row">
  3. <div class="col-md-4 col-xs-4">
  4. <ul class="list-group">
  5. {{#each model as |item|}}
  6. <li class="list-group-item">
  7. {{#link-to 'articles.article' item.id}}
  8. {{item.title}} -- <small>{{item.category}}</small> -- <small>{{item.author.username}}</small>
  9. {{/link-to}}
  10. <button {{action 'delById' item.id}}>删除</button>
  11. </li>
  12. {{/each}}
  13. </ul>
  14. // ……省略其他代码
  15. </div>
  16. </div>

截图

结果如上图,点击第二条数据删除按钮。弹出提示窗口,点击“确定”之后成功删除数据,并弹出“删除成功!”,到firebase后台查看数据,确实已经删除成功。 然而与此关联的user却没有删除,正常情况下也应该是不删除关联的user数据的。 最终结果只剩下一条数据:

截图

到此,有关新增、更新、删除的方法介绍完毕。已经给出了详细的演示实例,我相信,如果你也亲自在自己的项目中实践过,那么掌握这几个方法是很容易的!
博文完整代码放在Github(博文经过多次修改,博文上的代码与github代码可能有出入,不过影响不大!),如果你觉得博文对你有点用,请在github项目上给我点个star吧。您的肯定对我来说是最大的动力!!

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号