资讯专栏INFORMATION COLUMN

从服务器获取数据,引入组件

codecook / 2687人阅读

摘要:博文原址从服务器获取数据,引入组件接着前面四篇环境搭建以及使用创建第一个静态页面引入计算属性动态内容模型,保存数据到数据库发布项目,加入功能清理模板,使用组件重构版本之后组件会越来越重要。

博文原址:从服务器获取数据,引入组件

接着前面四篇:

环境搭建以及使用Ember.js创建第一个静态页面

引入计算属性、action、动态内容

模型,保存数据到数据库

发布项目,加入CRUD功能

清理模板,使用组件重构

2.0版本之后组件会越来越重要。有关组件的介绍请看Ember.js 入门指南之二十八组件定义。组件的创建同样可以使用Ember CLI命令创建。如下命令创建了2个组件,创建的同时会自动创建2个文件;一个是组件类(app/components/xxx.js)。一个是组件对应的模板(app/templates/components/xxx.hbs)。

ember g component library-item
ember g component library-item-form

修改模板library-item

下面在组件模板library-item.hbs中增加如下代码:


{{item.name}}

Address: {{item.address}}

Phone: {{item.phone}}

如果注意看可以发现上述代码与app/templates/libraries/index.hbs文件的代码非常相似。这是item替代了model。至于item是怎么来的请看Ember.js 入门指南之二十九属性传递,这篇博文介绍了组件的属性传递,item是从调用组件的模板传递过来的。上述代码中还有一个重要的东西是{{yield}},这个表达式与{{outlet}}类似。同样也是一个占位符。组件渲染之后会被传进来的html代码替换。比如下面的调用代码:

{{#library-item item=model}}
  Closed
{{/library-item}}

组件渲染之后,上述的Closed会替换到{{yield}}这里,最终得到的html代码如下:

有关组件渲染的内容请看Ember.js 入门指南之三十包裹内容。

修改模板library-item-form


{{input type="text" value=item.name class="form-control" placeholder="The name of the Library"}} {{#if item.isValid}}{{/if}}
{{input type="text" value=item.address class="form-control" placeholder="The address of the Library"}}
{{input type="text" value=item.phone class="form-control" placeholder="The phone number of the Library"}}

注意观察上述代码与libraries/new.hbslibraries/edit.hbs几乎是一样的。有点不一样的是把校验移到model中。比如校验name属性不为空。
注意:顶部导入的代码。

import Model from "ember-data/model";
import attr from "ember-data/attr";
import Ember from "ember";

export default Model.extend({
  name: attr("string"),
  address: attr("string"),
  phone: attr("string"),

  isValid: Ember.computed.notEmpty("name")
});

再修改app/templates/libraries/index.hbs引入组件。

List

{{#each model as |library|}}
{{#library-item item=library}} {{#link-to "libraries.edit" library.id class="btn btn-success btn-xs"}}Edit{{/link-to}} {{/library-item}}
{{/each}}

在迭代中使用组件,通过属性名item传递迭代出来的对象library到组件中。其中link-tobutton这两句代码会替换到组件library-item{{yield}}上。
等待项目重启完成,可以看到界面与之前的没有任何变化。页面是没有变化,但是后台的处理还需要完善。

修改app/templates/libraries/new.hbs


Add a new local Library

{{library-item-form item=model buttonLabel="Add to library list" action="saveLibrary"}}
{{#library-item item=model}}
{{/library-item}}

修改app/templates/libraries/edit.hbs

Edit Library

{{library-item-form item=model buttonLabel="Save changes" action="saveLibrary"}}
{{#library-item item=model}}
{{/library-item}}

在组件类library-item-form.js增加对action的处理。

import Ember from "ember";

export default Ember.Component.extend({
  buttonLabel: "Save",

  actions: {

    buttonClicked(param) {
      this.sendAction("action", param);
    }

  }
});
合并edit.hbsnew.hbsform.hbs

原来的文件edit.hbsnew.hbs几乎是一样的,可以使用组件重构。


{{title}}

{{library-item-form item=model buttonLabel=buttonLabel action="saveLibrary"}}
{{#library-item item=model}}
{{/library-item}}

为了实现代码复用,首先把不同的部分定义成属性:titlebuttonLabel。默认情况下路由会渲染到同名的模板上,如果你想修改这个默认行为可以使用renderTemplate()方法。

使用方法renderTemplate()setupController()

API介绍

renderTemplate()

setupController()

默认情况下路由会渲染到同名的模板上,我们使用方法renderTemplate()执行渲染的模板。比如下面的代码使用这个方法执行路由new渲染到模板libraries/form.hbs

// app/routes/libraries/new.js
import Ember from "ember";

export default Ember.Route.extend({

  model: function () {
    return this.store.createRecord("library");
  },

  setupController: function (controller, model) {
    this._super(controller, model);

    controller.set("title", "Create a new library");
    controller.set("buttonLabel", "Create");
  },

  renderTemplate() {
    this.render("libraries/form");
  },

  actions: {

    saveLibrary(newLibrary) {
      newLibrary.save().then(() => this.transitionTo("libraries"));
    },

    willTransition() {
      let model = this.controller.get("model");

      if (model.get("isNew")) {
        model.destroyRecord();
      }
    }
  }
});

注意方法setupController()设置组件模板中的属性titlebuttonLabel的值。同样的在修改路由edit.js

// app/routes/libraries/edit.js
import Ember from "ember";

export default Ember.Route.extend({

  model(params) {
    return this.store.findRecord("library", params.library_id);
  },

  setupController(controller, model) {
    this._super(controller, model);

    controller.set("title", "Edit library");
    controller.set("buttonLabel", "Save changes");
  },

  renderTemplate() {
    this.render("libraries/form");
  },

  actions: {

    saveLibrary(newLibrary) {
      newLibrary.save().then(() => this.transitionTo("libraries"));
    },

    willTransition(transition) {
      let model = this.controller.get("model");

      if (model.get("hasDirtyAttributes")) {
        let confirmation = confirm("Your changes haven"t saved yet. Would you like to leave this form?");

        if (confirmation) {
          model.rollbackAttributes();
        } else {
          transition.abort();
        }
      }
    }
  }
});

使用组件重构之后可以删除app/templates/libraries/new.hbsapp/templates/libraries/edit.hbs,这两个文件不需要了。效果截图如下:

使用组件nav-link-to重构
  • 知道组件如何使用之后我们继续重构项目代码,重构导航模板navbar.hbs的链接代码。使用Ember CLI命令创建组件。

    ember g component nav-link-to

    这次使用扩展的方式扩展一个组件类,扩展Ember内置的组件类LinkComponent,使用方法extend()扩展一个类。然后使用属性tagName指定渲染之后的标签。更多有关组件属性的介绍请看Ember.js 入门指南之三十一自定义包裹组件的HTML标签,当然你也可以参考网址的教程实现本文的需求。

    // app/components/nav-link-to.js
    import Ember from "ember";
    
    export default Ember.LinkComponent.extend({
      tagName: "li"
    });

    注意:记得修改Ember.Component.extendEmber.LinkComponent.extend。组件模板很简单。

    
    {{yield}}

    最后在修改导航模板navbar.hbs为如下内容:

    
    

    等待项目重启完成,可以看到界面与之前的没有任何变化,可以任意点击导航栏菜单且不会出错。效果截图如下:

    家庭作业

    本篇的家庭作业就是好好理解组件!参考下面的文章认真学习、理解组件。

    Ember.js 入门指南之二十八组件定义

    Ember.js 入门指南之二十九属性传递

    Ember.js 入门指南之三十包裹内容

    Ember.js 入门指南之三十一自定义包裹组件的HTML标签

    Ember.js 入门指南之三十二处理事件

    Ember.js 入门指南之三十三action触发变化



    为了照顾懒人我把完整的代码放在GitHub上,如有需要请参考参考。博文经过多次修改,博文上的代码与github代码可能有出入,不过影响不大!如果你觉得博文对你有点用,请在github项目上给我点个star吧。您的肯定对我来说是最大的动力!!

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/79533.html

    相关文章

    • 【CuteJavaScript】Angular6入门项目(3.编写服务引入RxJS)

      摘要:发布通过回调方法向发布事件。观察者一个回调函数的集合,它知道如何去监听由提供的值。 本文目录 一、项目起步 二、编写路由组件 三、编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四、编写服务 1.为什么需要服务 2.编写服务 五、引入RxJS 1.关于RxJS 2.引入RxJS 3.改造数据获取方式 六、改造组件 1.添...

      RebeccaZhong 评论0 收藏0
    • 【CuteJavaScript】Angular6入门项目(2.构建项目页面和组件

      摘要:编写单一组件我们首先写一个书本信息的组件,代码如下单个课本像火焰像灰烬程姬知识点是一个的复写器指令,就像中的和中的。写到这里,看看我们项目,还是一样正常在运行,只是现在项目中组件分工更加明确了。 本文目录 一、项目起步 二、编写路由组件 三、编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四、编写服务 1.为什么需要服务 2.编写服务 五、...

      Lemon_95 评论0 收藏0
    • 使用纯粹的JS构建 Web Component

      摘要:它赋予了仅仅使用纯粹的就可以创建可重用组件的能力。我们会用到的来创建我们的用户卡片。在较早版本的浏览器中,我们不能使用来隔离组件。这可以部分归咎于对的影响很大的。你可以在这里阅读第二部分的教程使用纯粹的构建 原文链接:https://ayushgp.github.io/htm...译者:阿里云 - 也树 Web Component 出现有一阵子了。 Google 费了很大力气去推动它更...

      Luosunce 评论0 收藏0
    • 使用纯粹的JS构建 Web Component

      摘要:它赋予了仅仅使用纯粹的就可以创建可重用组件的能力。我们会用到的来创建我们的用户卡片。在较早版本的浏览器中,我们不能使用来隔离组件。这可以部分归咎于对的影响很大的。你可以在这里阅读第二部分的教程使用纯粹的构建 原文链接:https://ayushgp.github.io/htm...译者:阿里云 - 也树 Web Component 出现有一阵子了。 Google 费了很大力气去推动它更...

      RayKr 评论0 收藏0

    发表评论

    0条评论

    最新活动
    阅读需要支付1元查看
    <