以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,你會發現它是很是容易轉換的
相關文章
相關標籤/搜索