Github 參考
還記得昨天說要偷懶一下嗎 XD
因為刪除真的很簡單!
我們前面走過了新增、修改、讀取了
刪除?哪有什麼困難的呢! XD
直接看 code 吧!
routes/users.js:
// Delete a todo task router.delete('/:user_id/todos/:todo_id', function(req, res) { var user_id = req.params.user_id; var todo_id = req.params.todo_id; TODO.remove( { _id: todo_id, user_id: user_id }, function (err) { if (err) { res.status(400).json( { error: "delete data error"} ); } else { res.status(201).json( { success: "true" } ); } } ); }); 非常的簡單!
先抓到 user_id, todo_id 後
使用 .remove 的方法,下 WHERE 條件,並在 callback 作處理
Github link
今天要來建立 “新增資料” 的頁面
不過這個頁面我們也會拿來給 “更新資料” 的頁面使用
原因其實很簡單
兩邊要建立或編輯的資料是一樣的
差別只在於,當今天是編輯資料的 view call 該頁面時,
該頁面除了顯示編輯框外,編輯框內的文字也會預先 load 好舊的資料了
除此之外兩個 view 的排版一模一樣
所以在這邊我們就只建立一個 UpdateViewController 就可以了
那我們一樣建立一組 UpdateViewController.swift + UpdateViewController.xib
也一樣為元件建立關聯
回到主頁
我們幫 Add 新增一個按鈕吧
在 viewDidLoad 中
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", style: UIBarButtonItemStyle.Done, target: self, action: Selector("pushToAddTODO")) 設定 Navigation 的右邊鍵的功能
並且根據 pushToAddTODO 的方法做事情
因此繼續下去將 pushToAddTODO 方法做一下
func pushToAddTODO(){ var addViewController = UpdateViewController(nibName: "UpdateViewController", bundle: nil) addViewController.from = "add" self.navigationController?.pushViewController(addViewController, animated: true) } 這樣寫完後就可以執行看看了!
Github 參考
接上篇,我們已經可以拿到 todo list 了
也可以拿到特定的 todo task
再來我們就可以編輯特定的 todo task 了對吧?
不囉唆直接進入程式碼
routes/users.js
// Update a todo task router.put('/:user_id/todos/:todo_id', function(req, res) { var user_id = req.params.user_id; var todo_id = req.params.todo_id; var data = req.body; TODO.update( { _id: todo_id, user_id: user_id }, { $set: { content: data.content } }, function (err, num, raw, results) { if (err) { res.status(400).json( { error: "update data error" } ); } else { TODO.
Github link
延續昨天,接下來要做換頁
因此我們必須先新建立一個 ShowViewController, 以及他的 xib
接著我們在 xib 拉幾個元件: 兩個 label, 一個用來顯示目前的 index, 另一個則是顯示內容
拉好後,將這兩個元件設定連結到 ShowViewController.swift
另外多在 ShowViewController 中放兩個變數
var index: Int! var content: String! 回到 ViewController, 到 tableView didSelectRowAtIndexPath 中
因為 didSelectRowAtIndexPath 的意思就是當 cell 被選取時要做什麼事情
因此當 cell 被選取時,我們就要讓他跳到下一頁,並且是使用 ShowViewController 來顯示資料
因此修改此方法:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { var showViewController = ShowViewController(nibName: "ShowViewController", bundle: nil) showViewController.index = indexPath.row showViewController.content = fakeData[indexPath.row]["content"] // 回復非選取狀態 tableView.deselectRowAtIndexPath(indexPath, animated: true) self.
Github 參考
如果有使用 MongoDB client 的話就可以搭配使用會比較有感覺
Mac 我是使用 Robomongo,算很好上手~
今天要來實作讀取的部分
讀取有分兩種,一種是讀取 list
另一種是讀取特定某個 todo task,今天兩種都會實作
首先我們先實作 get todo list
因為若要拿到特定的 todo task,需要 todo task 的 id
而我們現在還不曉得 todo task 的 id 是多少,我們只知道 user_id
因此就先從 list 下手
routes/users.js:
// Get todo list router.get('/:user_id/todos', function(req, res) { var user_id = req.params.user_id; TODO.find( {user_id: user_id}, function (err, results) { if (err) { res.status(400).json( { error: "can not find data" } ); } else { res.
Github link
接著我們要讓主頁顯示一些假資料:
由於我們未來接的 api 的資料會是 todo_id + content
因此我們先產生一個 dictionary array 來存放我們的假資料
var fakeData = [[String:String]]() fakeData = [ ["id": "1", "content": "A"], ["id": "2", "content": "B"], ["id": "3", "content": "C"], ] 再來對主頁的 controller 新增 tableView 上去
並且對 UITableView 加入 delegate 以及 datasource
import UIKit class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { var fakeData = [[String:String]]() var tableView: UITableView? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib.
Github 參考
昨天我們了解了如何拿 url params 以及 request data
今天我們就來使用他,對資料庫做存取
由於使用到資料庫,因此我們要加入資料庫的 driver
我們用的是 mongoose 套件
app.js:
// 在最上方加入 var mongoose = require('mongoose'); // 在某個地方連接資料庫 var db_uri = "mongodb://192.168.33.10:27017/TODOs"; mongoose.connect(db_uri); 在這邊我是使用了虛擬機的 DB,因此是 mongodb://192.168.33.10:27017/TODOs
DB 的名稱為 TODOs
這樣在程式一跑起來時,就會連接資料庫了!
再來我們就要設定在對資料庫做 CRUD 時,所需要做的事情
首先我們先要定義 schema,
雖然 mongodb 是 schema-free,但是官方文件也有提到最好還是有固定的 schema 避免記憶體 allocate 時出現問題,而程式撰寫時邏輯也不會因此而過於複雜
這時候我們就需要 model 資料夾了,在 model 資料夾中新增一個 todos.js
裡面要放的就是 todo task 的 schema
內容如下:
models/todos.js:
'use strict'; var mongoose = require('mongoose'); // Define our todo schema var TODOschema = new mongoose.
Github link
首先在開始寫這隻 app 前,
我們要先定義好程式大致上的流程
基本上接下來的程式碼都不會用到 storyboard
只會用到程式 + xib
程式的流程大致上是使用 Navigation controller 來控制 view 的轉換
第一頁 - tableView 顯示 todo items list
點進子項目可以觀看內容,進到子頁後可以編輯,
編輯後就即可存檔
新增項目則在主頁的右上角 “Add” 可以新增
我們會先從建立假的資料開始,也就是我會先刻出程式的流程
先不接 API
實際寫出運作流程後,再加上 API 操作的部分
因此今天的進度就先開一個新專案,將基本的 Navigation + tableView 建立起來吧:
首先建立一個新專案
再來到 project settings
將 Main Interface 及 Launch Screen file 拿掉
並將 deploy target 設成 7.1 (反正用到的程式碼都一樣~ 沒有特別使用 8.0 的 lib)
設定 device orientation - 只限定直的
接著就來編輯 AppDelegate.swift
建立一個 NavigationController + ViewController
Github 參考
接著我們要根據我們開之前寫好的 文件 來開發:
要有下列 routes
TODOs GET /user/{user_id}/todos/ POST /user/{user_id}/todos/ GET /user/{user_id}/todos/{id} PUT /user/{user_id}/todos/{id} DELETE /user/{user_id}/todos/{id} 這樣的需求其實可以用 namespace 實作,不過我們偷懶一點,直接指向 /user 就好
所以在 app.js 加入
var users = require('./routes/users'); app.use('/user', users); 所以會變這樣:
var express = require('express'); var app = express(); // Set routers var index = require('./routes/index'); var users = require('./routes/users'); app.use('/', index); app.use('/user', users); module.exports = app; 不過看起來我們缺少 routes/users.js,所以我們也來新增一個
routes/users.js 內容如下
'use strict'; var express = require('express'); var router = express.
今天專案的 Github link
其實哦
寫 Swift 也有幾個禮拜了
我一直覺得使用 Interface Builder 的確很方便
但是在程式面與視覺面之間的溝通常常會漏東漏西的
比方說如果要設定 reusable identifier 時
除了程式裡面的字串要設定以外,還要再到 storyboard 裡設定同樣的字串
一個簡單的小程式可能不超過 20 個 View 的情況下
還可以這樣做,當程式長得非常大的時候,好像就很難注意到這件事,
而且 View 太多 storyboard 就會開始變慢….
因此今天要來試著在 Swift 中
如何不用 Storyboard,來打造我們的程式
(當然 xib/nib 還是會用到,只是我們單純捨棄 storyboard,用程式來控制流程)
首先,一樣先建立一個測試專案
接著我們要動到的程式碼是 AppDelegate.swift:
編輯它:
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var viewController: ViewController? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch.