以ToDoList应用来学习Geddy

Geddy学习笔记

初始工具安装 Node.js, Geddy, Jake

本文运行环境为Windows,Node.js安装比较简单,进入Node.js官网直接下载安装包傻瓜安装便可。html

安装Geddy,打开终端cmd.exe,输入$ npm install -g geddynpm

安装Jake,输入 $ npm install -g geddy jakejson

geddy gen命令

应用例子:浏览器

$ geddy gen scaffold book title:string descrption:text

  $ geddy gen scaffold user name:default

Geddy的生成器命令包括有:app

  • app <name>
  • secret
  • scaffold <name> [model properties]
  • resource <name> [model attributes]
  • controller <name>
  • model <name> [model attributes]

其中,这三个命令'scaffold', 'resource', 'model'包括以空格分隔的Model属性编辑器

构建一个App

新建工做目录,进入目录路径,ide

敲入命令:$ geddy gen app to_do函数

生成文件夹及文件,具体含义请参考http://geddyjs.org/tutorial#building_an_app工具

如今打开你简单的初级geddy应用:post

$ cd to_do
  $ geddy

以后打开浏览器输入 localhost:4000 ,你就进入hello world页面了

建立“资源”

如今咱们为ToDo项目建立“资源”,ToDo项目包括title, status

$ geddy gen scaffold to_do title:default status

建立后,再从新打开cmd,重启Geddy:

$ geddy

再打开浏览器到 localhost:4000/to_dos (URL地址就是在后面加个 app name 多个s),而后咱们就看到ToDoList的App页面了

添加验证功能

在项目里打开 'app/model/to_do.js' ,添加如下代码对title, status进行验证:

var ToDo = function(){
    ...

    this.validatesPresent('title'),
    this.validatesLength("title", {min: 5});

    this.validatesWithFunction('status', function(status){
      return 'open' === status || 'done' === status;
    }, {message: "Status must be 'open' or 'done'."});
    ...
  };
  ToDo = geddy.model.register("ToDo", ToDo);

代码很简单,你们测试一下ToDoList的App,添加和编辑ToDo项目

建立关联

如今咱们建立另一个“资源”,使它关联到咱们的ToDos。

假设ToDo项目有几个步骤才行完成建立的,如今咱们就scaffold out步骤“资源”:

$ geddy gen scaffold step title:default description:text status

添加步骤验证

如今咱们能够关联步骤和ToDo项目了。接着咱们添加每一个步骤都必须有一个'title'的验证——添加如下代码到你的步骤模型里(app/models/step.js):

var Step = function(){
    ...

    this.validatesPresent('title'),           // 同ToDo的验证同样
    this.validatesLength("title", {min: 5});

    this.validatesWithFunction('status', function(status){
      return 'open' === status || 'done' === status;
    }, {message: "Status must be 'open' or 'done'."});
    ...
  };
  Step = geddy.model.register("Step", Step);

建立关联

如今咱们为建立的ToDo和Step俩模型建立关联。

添加下面代码到ToDo模型里:

var ToDo = function () {
  ...
    this.hasMany('Steps');
  ...
  };
  ToDo = geddy.model.register('ToDo', ToDo);

这代表一个ToDo能够有多个关联的Step(1对n)。

接着,添加下面代码到Step模型里:

var Step = function () {
  ...
    this.belongsTo('ToDo');
  ...
  };
  Step = geddy.model.register('Step', Step);

这代表每个Step都会被一个ToDo拥有。(1对1)

显示关联

打开 localhost:4000/steps 可看到Steps的空列表。

而后虽然咱们能够添加Step,但没有选项给咱们选择关联的ToDo项目。

下面让咱们来修复这个问题,思路是获取ToDos里的数据,而后加载到页面中一个下拉框供选择。

获取ToDos

用编辑器打开 'app/controllers/steps.js' ,看到 'add' 动做( this.add ,Step Controller的一个方法)。

接着,咱们用Geddy ORM的 all 方法去获取以前添加的ToDos项目。这个在渲染Step编辑页面以前完成:

this.add = function (req, resp, params) {
    var self = this;
    geddy.model.ToDo.all(function(err, data){
      if(err) throw err;

      self.respond({params: params, toDos: data});
    });
  };

上面获取ToDo项目的数据了,并在回调函数中做为 toDos 参数传到Step的'编辑'页面。

传递数据给表单

打开 app/views/steps/add.html.ejs。这是一个被 'add' 添加和 'edit' 编辑页面共享的表单,它被渲染为一个 'partial'。

如今需把ToDos的数据传给 'partial' ,在 'partial' 那行,把该行代码改成这样:

<%- partial('form', {step:{}, toDos: toDos}) %>

显示ToDos在下拉框中

如今咱们打开 'partial' 模板 'app/views/steps/form.html.ejs' ,咱们准备把ToDos的数据扔到一个下拉框里。

Geddy有不少好用方便的助手工具,好比 selectTag,和其余好多好多。你能够参考 助手工具文档

在div.control-group里,以下添加下拉框:

<label for="title" class="control-label">To-Do for this step</label>
  <div class="controls">
    <%- selectTag(toDos, step.toDoId, {
      name: 'toDoId'
    , valueField: 'id'
    , textField: 'title'
    }); %>
  </div>

第二个参数 step.toDoId 指定哪一个元素会被默认选择。这个如今还没起做用,但在咱们开始编辑Steps时它就有效了。

保存Step

这时建立一个新的Step,看看它有没toDoId(与相关的ToDo项目的ID对应),若是有的话就表示关联正确,若冇则否。

编辑Step

与前面调整 'add' 执行动做同样,这里也要调整 'edit' 执行动做。打开Step Controller,更改 'edit' 以下:

this.edit = function (req, resp, params) {
    var self = this;
    geddy.model.Step.first(params.id, function(err, step) {
      if (err) {
        throw err;
      }
      if (!step) {
        throw new geddy.errors.BadRequestError();
      }
      else {
        geddy.model.ToDo.all(function (err, data) {
          if (err) {
            throw err;
          }
          self.respond({step: step, toDos: data});
        });

        // self.respondWith(step);
      }
    });
  };

重要提示:原来的 respondWith 方法被替换为低级的 respond 了。当你只有一个model的实例时,使用 respondWith 方法是很方便的,但这里要传递一些数据,因此要用 respond 方法。

点击这里 学习更多响应请求的方法。

如今打开 'app/views/steps/edit.html.ejs' ,传递 toDos 给 'partial' :

<%- partial('form', {step: step, toDos: toDos}) %>

如今建立更多的Step,并把它们关联到同一个ToDo项目。这时,咱们也要关注另外一个问题:在ToDo项目视图下显示全部的Step。

在toDo这边的关联

打开ToDo的Controller 'app/controllers/to_dos.js',更新 'show' 执行动做来获取全部与某特定的ToDo项相关的Steps:

this.show = function (req, resp, params) {
    var self = this;

    geddy.model.ToDo.first(params.id, function(err, toDo) {
      if (err) {
        throw err;
      }
      if (!toDo) {
        throw new geddy.errors.NotFoundError();
      }
      else {
        toDo.getSteps(function (err, data) {
          self.respond({toDo: toDo, steps: data});
        });
      }
    });
  };

注意到上面代码的 first 执行来获取第一个匹配特定id的ToDo项目。而注意到toDo实例有 getSteps 的方法来获取相关联的Steps数据,这是Geddy提供的方便方法:若是ToDo设置了 hasMany 的 'Zoobie' 的项目,Geddy会自动生成 getZoobies 方法来获取它们。

另外,至于 respondWith 方法被替换为 respond ,这个的缘由和做用前面已说起。

如今,打开 'show' 视图(app/views/to_dos/show.html.ejs),再修改下。

底部的代码经过遍历toDo的属性来检验该项是否已经被保存了,但这个是默认生成的不起做用的代码,咱们把它替换为如下的内容:

<h3>Status: <%= toDo.status %></h3>

  <h3>Steps</h3>
  <% steps.forEach(function (step) { %>
  <h4>
    <%- linkTo(step.title, {controller: 'steps', action: 'show', id: step.id}); %>
  </h4>
  <% }); %>

代码遍历该ToDo项关联的Steps,生成以step的title为文字、和连接到step的 'show' 执行动做的url的连接。

API

检验下如下的url:

  • GET: localhost:4000/to_dos.json (ToDo项目列表,JSON字符串显示)
  • GET: localhost:4000/to_dos/:id.json (id为:id的toDo的详情,包括steps,JSON字符串显示)
  • POST: localhost:4000/to_dos (页面显示)
  • PUT: localhost:4000/to_dos/:id (页面显示)

总结

如今你已经完成了一个ToDoList的Geddy应用。若是你想探索更多,能够试下:

  • 改变 Main#index 路由为 ToDos#index (提示:check out 'config/router.js')
  • 利用 geddy.log 添加一些log
  • 配置 'mongo', 'riak' 或者 'postgress' 来替换memory modelAdapter,你会发现它是很是容易转换的
相关文章
相关标签/搜索