連接 DB 是一件必定要進行的事,在 Laravel 可以使用 ORM 去完成,而在 NodeJS 上,筆者用得最多是使用 npm mysql 去完成。雖然 NodeJS 上的 mysql library 是一個寫得很成熟的東西,但是在建立 query 時還是有很多不足的地方。最明顯的地方是在建立 conditional where 時。 ### 例子 以下是一個壞的例子 : ```js var sqlParams = []; var where = []; // conditional where case if( typeof id === 'number' ) { where.push('id = ?'); sqlParams.push(id) } // sql var sql = 'select * from users where ' + where.join(' and '); // execute query db.query(sql, sqlParams, callback); ``` 相信這樣的 SQL Statement 大家都有可能寫過 / 見識過。雖然上面的寫法還不致於十分混亂,但是讀起來也不是太方便。如果又要同時用上 AND 及 OR 時,可能就會出現比較混亂的情況了 ! ### Knex.js - A SQL Query Builder for Javascript 這是 Knex.js 自己介紹自己的,它是一個 SQL Query Builder。 不過除此之後它還會自行管理 Connection 的生命週期,使用 Connection Pool 的話還會自行 release connection,算是一個非常便利及強勁的 Database adapter。 官方網站 : http://knexjs.org 以下是使用 Knex 的方法來重寫一次上面的代碼 : ```js // query var query = knex('users'); // conditional where case if( typeof id === 'number' ) { query.where('id', id); } // execute query var result = await query; ``` 很神奇吧。
在大多數的情況下,如果需要對調兩個變數的值,就需要使用到第三個變數來記錄暫存的值 : ```js temp = x; x = y; y = temp; ``` 然而,其實是可以使用 XOR 來耍點技巧來達成,不需要使用到 temp 變數 : ```js x = x xor y; y = x xor y; x = x xor y; ``` 不相信 ? 以下會進行一個實際的例子。 ```js // init values var x = 34; // 34 var y = 78; // 78 // do the swap x = x xor y; // 108 y = x xor y; // 34 x = x xor y; // 78 // final values y; // 34 x; // 78 ``` ### 什麼是 XOR XOR 是對 bit 的運算,以下例子可以說明 XOR 的動作 : |x|y|x xor y| |---| |0|0|0| |0|1|1| |1|0|1| |1|1|0| ### 動作分析 我們把上面的操作,使用不同的變數儲存起來,就會比較容易看得出分別。 ```js x1 = x xor y y1 = x1 xor y x2 = x1 xor y1 ``` 使用上面的數字 ( x = 34, y = 78 ),我們使用二進為計算一下。 #### 第一步 ```js x1 = x xor y ``` 我們使用二進位來計算說明 : ||||||||| |---| |||1|0|0|0|1|0| |xor|1|0|0|1|1|1|0| ||1|1|0|1|1|0|0| 而二進位 1101100 就是十進位的 108。 #### 第二步 ```js y1 = x1 xor y ``` 我們使用二進位來計算說明 : ||||||||| |---| ||1|1|0|1|1|0|0| |xor|1|0|0|1|1|1|0| ||0|1|0|0|0|1|0| 而二進位 100010 就是十進位的 34,已經把 x 的值移到 y 去了。 #### 最後一步 ```js x2 = x1 xor y1 ``` 我們使用二進位來計算說明 : ||||||||| |---| ||1|1|0|1|1|0|0| |xor||1|0|0|0|1|0| ||1|0|0|1|1|1|0| 而二進位 1001110 就是十進位的 78,已經把 y 的值移到 x 去了。 這樣就已經完成把變數 x 和 y 互換了 ! ### 使用純數的角度去證明 以下是證明 x2 = y 的算式 : ```js x2 = x1 xor y1; x2 = x1 xor (x1 xor y); // replace y1 x2 = (x1 xor x1) xor y; // associative law x2 = 0 xor y; // a xor a => 0 x2 = y; // 0 xor a => a; x2 now has y's original value ``` 以下是證明 y1 = x 的算式 : ```js y1 = x1 xor y y1 = (x xor y) xor y y1 = x xor (y xor y) y1 = x xor 0 y1 = x ``` 很有趣吧 !
在 ExtJS 內,我們會用 Proxy 來載入 Store 內容。以下是 Proxy 會自動加入的參數 : - start - (number) 像 SQL 的 offset - limit - (number) 像 SQL 的 limit - page - (number) 頁數 - sort - (string) JSON format 的字串,用來排列結果 但是有時我們可能需要加入更多的參數才可以抽出資料,那應該要怎樣做呢? ### 動態方法 可以通過使用 `Proxy.setExtraParams()` 來動態設定額外的參數。 ```js grid.getStore().getProxy().setExtraParams({ foo: 'bar' }); grid.getStore().load(); ``` ### 靜態方法 可以通過加入 `extraParams` 到 Proxy 來設定額外的參數。 ```js new Ext.data.Store({ autoLoad: true, proxy: { url: 'users.php', type: 'ajax', extraParams: { foo: 'bar' } } }); ```
使用 ExtJS 就一定會自定義一些 Component 來使用,而自定義的 Component 如果要把 UI 的互動動作傳出去的話,就需要自定義 Event 了。 ### 自定義 Component 看看下面例子 : ```js Ext.define('MyApp.CustomForm', { extend: 'Ext.form.Panel', layout: { type: 'vbox' }, items:[{ xtype: 'textfield', name: 'name' }, { xtype: 'button', text: 'submit' }] }); ``` 上面定義了一個 `MyApp.CustomForm` 元件,入面定義了一個 submit button。如果要把 submit button 的 click 事件傳出去給 `MyApp.CustomForm` 接收,應該要怎樣做呢? ### 使用 `.fireEvent()` 方法 我們可以通過使用 `.fireEvent()` 方法來對元作發動事件 : ```js { xtype: 'button', text: 'submit', listeners: { click: function(ele) { ele.up('form').fireEvent('submitclick', 'message'); } } } ``` 上面的代碼是使用 `MyApp.CustomForm`發動 `submitclick` 事件,並傳入 'message' 字串作為參數。 在生成 `MyApp.CustomForm` 元件時,我們可以設定 `submitclick` 事件的 listener。 ```js var form = Ext.create('MyApp.CustomForm'); form.on('submitclick', function(message) { console.log(message); }); ``` 這樣當 `MyApp.CustomForm` 內的 `button` 按下時,`MyApp.CustomForm` 就會發動 `submitclick` 事件所連結的 listeners。