Meteor項目實戰 -- Next 0.0.1

學了一段時間Meteor以後,着手作一個APP,關於時間管理的,取名 Nextcss

Get things done , and do Nexthtml

同時,把開發過程儘量詳細的記錄下來,分享給有須要的同窗。前提是你有一些Meteor基礎,至少要了解各類基礎概念:集合、發佈訂閱、method、package等。git

若是以前沒了解過Meteor,能夠快速過一遍meteor教程github

Next 0.0.1版的目標是任務列表,四象限展現,能夠新增、修改和刪除任務。最後的效果以下圖:(後面會慢慢提高她的顏值)shell

Next 0.0.1 效果圖

項目初始化

新建項目數據庫

meteor create next

進入項目目錄,並啓動api

cd next
meteor

打開瀏覽器,訪問 http://localhost:3000,會看到自動生成的demo。瀏覽器

刪除自動生成的文件,並創建項目目錄結構app

rm next.css next.html next.js
mkdir client public server lib

添加路由包iron:router;因爲後面會用coffeescript寫,因此還要加上coffeescript框架

meteor add iron:router
meteor add coffeescript

第一條路由和模板

基本的骨架都有了,能夠開始敲代碼了。在client文件夾中新建router.coffee,內容以下:

Router.route('/', ->
  @render("Home")
)

瀏覽器中顯示了一條錯誤信息:找不到home模板

Couldn't find a template named "Home" or "home". Are you sure you defined it?

接下來定義home模板,在client文件夾中新建templates文件夾,在裏面新建home.html,內容以下:

<template name="home">
    welcome to home
</template>

此時瀏覽器顯示:

welcome to home

新建collection

在lib文件夾中新建collections文件夾,在裏邊新建task.coffee,內容以下:

@Task = new Mongo.Collection('task')

Task collection就對應數據庫裏的一張表,根據需求,初步設計了下面幾個字段:

name 任務名稱
important 是否重要
urgent 是否緊急
complete 是否完成
create_time 建立時間
complete_time 完成時間

爲了方便調試,要製造一些初始數據。在server文件夾下新建init_data.coffee

Meteor.startup(->
  if Task.find().count() is 0
    Task.insert
      name: "晚上和妹子去吃飯"
      important: true
      urgent: true
    Task.insert
      name: "翻譯Meteor文檔"
      important: true
      urgent: false
    Task.insert
      name: "看完《悲傷與理智》"
      important: false
      urgent: false
    Task.insert
      name: "給手機充話費"
      important: false
      urgent: true
)

解釋下上面的代碼:每次啓動Meteor的時候,查詢任務條數,若是條數爲零,則插入四條初始數據。

以後打開數據庫看看是否插入成功,打開一個新的命令行窗口,切換到項目根目錄:啓動mongo shell

meteor mongo

查詢任務條數:

db.task.find().count()
1

明明插入了四條,爲何只查詢到一條呢?由於在編碼過程當中,Meteor會監測源碼的變化並自動從新運行,當剛寫完第一條插入語句,Meteor可能就從新運行了,此時任務條數爲1,後面的插入就不會再執行了。

接下來須要control+c 中止Meteor進程,重置並重啓

meteor reset
meteor

再次到mongo shell中查詢任務條數:

db.task.find().count()
4

將數據展現到前臺界面

能夠經過Helper給模板增長動態數據,在templates文件夾中新建home.coffee,內容以下:

Template.home.helpers
  taskList: ->
    Task.find()

修改home.html

<template name="home">
    {{#each taskList}}
        {{name}}
    {{/each}}
</template>

瀏覽器顯示

晚上和妹子去吃飯 翻譯Meteor文檔 看完《悲傷與理智》 給手機充話費

這裏有一個問題須要思考:爲何客戶端沒有進行任何請求,數據就從服務端到了客戶端?

這是由於:爲了簡化開發,每一個新建的Meteor項目都會包含一個autopublish包,這個包會把全部集合裏的文檔自動發佈到每個鏈接上的客戶端。爲了可以精確地控制文檔的發佈,須要移除autopublish,而後手動進行發佈與訂閱

meteor remove autopublish

此時瀏覽器中顯示頁面爲空。接下來,在server目錄下新建publish.coffee

Meteor.publish('tasks', ->
  Task.find()
)

在client目錄下新建subscribe.coffee

Meteor.subscribe('tasks')

這時候瀏覽器中的頁面數據就又都回來了。

頁面樣式調整

項目用到了yahoo的pure css框架:點我下載

在client文件夾下新建style文件夾,將pure-min.css放進去,而後再新建一個todo.css

將home.html 的佈局修改成四象限

<template name="home">
    <div class="pure-g main-container">
        <div class="pure-u-1-2 task-list-wrapper task-list-wrapper-tl">
            <div class="task-list-title">
                重要&緊急
            </div>
            <ul class="task-list"></ul>
        </div>
        <div class="pure-u-1-2 task-list-wrapper  task-list-wrapper-tr">
            <div class="task-list-title">
                重要&不緊急
            </div>
            <ul class="task-list"></ul>
        </div>
        <div class="pure-u-1-2 task-list-wrapper  task-list-wrapper-bl">
            <div class="task-list-title">
                不重要&緊急
            </div>
            <ul class="task-list"></ul>
        </div>
        <div class="pure-u-1-2 task-list-wrapper  task-list-wrapper-br">
            <div class="task-list-title">
                不重要&不緊急
            </div>
            <ul class="task-list"></ul>
        </div>
    </div>
</template>

在todo.css 裏增長樣式

html, body {
    height: 100%;
}

.main-container {
    height: 100%;
}

.task-list-wrapper {
    height: 50%;
}

.task-list-wrapper-tl {
    background-color: #ffaeae;
}

.task-list-wrapper-tr {
    background-color: #56baec;
}

.task-list-wrapper-bl {
    background-color: #ffec94;
}

.task-list-wrapper-br {
    background-color: #b4d8e7;
}

接下來修改home模板的Helper

Template.home.helpers
  taskListTL: ->
    Task.find({important: true, urgent: true})
  taskListTR: ->
    Task.find({important: true, urgent: false})
  taskListBL: ->
    Task.find({important: false, urgent: true})
  taskListBR: ->
    Task.find({important: false, urgent: false})

修改home.html,將對應的Helper展現到對應的板塊,例如:

<div class="pure-u-1-2 task-list-wrapper task-list-wrapper-tl">
            <div class="task-list-title">
                重要&緊急
            </div>
            <ul class="task-list">
                {{#each taskListTL}}
                    <li>{{name}}</li>
                {{/each}}
            </ul>
        </div>

此時效果以下圖:

next 0.0.1 四象限

新增任務

修改home.html,給每一個版塊增長一個form表單,用於新增任務

<div class="pure-u-1-2 task-list-wrapper task-list-wrapper-tl">
            <div class="task-list-title">
                重要&緊急
            </div>
            <form class="pure-form form-create-task">
                <input class="hidden" type="text" name="type" value="tl"/>
                <input class="pure-input-1" name="name" type="text"/>
                <button class="hidden" type="submit"></button>
            </form>
            <ul class="task-list">
                {{#each taskListTL}}
                    <li>{{name}}</li>
                {{/each}}
            </ul>
        </div>

表單裏有一個隱藏的輸入框,用於標識任務的類別,分別是:tl,tr,bl,br
接下來,須要讓模板監聽表單的提交事件,並作處理。

在home.coffee 中增長:

Template.home.events
  'submit .form-create-task': (e)->
    e.preventDefault()
    $form = $(e.currentTarget)
    task =
      name: $form.find('input[name=name]').val()
      create_time: new Date()
      important: false
      urgent: false
    type = $form.find('input[name=type]').val()

    switch type
      when 'tl'
        task.important = true
        task.urgent = true
      when 'tr' then task.important = true
      when 'bl' then task.urgent = true
    console.log task
    Task.insert(task)
    $form.find('input[name=name]').val('')

首先阻止表單的默認提交,而後從表單中提取所需值,構建一個task對象,經過Task.insert()插入到數據庫,而後清空表單。

在瀏覽器中測試沒有問題,新增任務的功能就完成了。

修改任務

修改home.html,修改任務列表爲:

<ul class="task-list">
                {{#each taskListTL}}
                    <li class="task-item" data-task-id="{{_id}}">
                        <div class="task-name" contenteditable="true">{{name}}</div>
                    </li>
                {{/each}}
            </ul>

修改home.coffee,監聽.task-name 上的回車事件:

'keypress .task-name': (e)->
    $el = $(e.currentTarget)
    taskId = $el.parent().attr('data-task-id')
    if e.keyCode is 13
      taskName = $el.text()
      Task.update({_id: taskId}, {$set: {name: taskName}})
      $el.blur()
      e.preventDefault()

瀏覽器中測試經過。

刪除任務

修改home.html,修改任務列表爲:

<ul class="task-list">
                {{#each taskListTL}}
                    <li class="task-item" data-task-id="{{_id}}">
                        <div class="task-name" contenteditable="true">{{name}}</div>
                        <span>&times;</span>
                    </li>
                {{/each}}
            </ul>

修改todo.css,調整樣式:

.task-item {
    position: relative;
    line-height: 25px;
}

.delete-task {
    position: absolute;
    top: 0px;
    right: 10px;
    cursor: pointer;
}

.delete-task:hover {
    color: #dd3023;
}

修改home.coffee,綁定刪除按鈕的點擊事件:

'click .delete-task': (e)->
    $el = $(e.currentTarget)
    taskId = $el.parent().attr('data-task-id')
    Task.remove({_id: taskId})

至此,Next 0.0.1 版本的需求就基本完成了。就是樣式醜了些,先不要在乎這些細節啦。後面再優化嘍。

原文地址:http://zicai.github.io/lessons/2015/06/22/meteor-in-action-next-0.0.1/

相關文章
相關標籤/搜索