jQuery 和 AngularJS 的不同思维模式
[文章引用]︰大置上分五點
- 先不要理會 UI 設計,應該用 DOM 去達成你的預期結果
在jQuery的裡面,你會先設計好一個頁面,然後再讓它變成動態的。
那就是問題所在,在開發後期,那會令到程式碼十分冗長︰難以閱讀、難以理解 邏輯 和 流程
但是在AngularJS的世界中,先要構思整體架構,然後從零開始構建應用。
而不是在現有的介面中,你要讓它做 ~!@#$%^ 就做,過了一會要多做幾樣,就再做幾樣
你必須首先思考你到底要完成什麼功能,然後再開始動手,
然後再開發你的應用,最後才去設計你的介面。
- 不要混合使用jQuery和AngularJS
就是字面的意思,原文提到 大多數情況 只需要很少的 AngularJS 代碼就可以把 150-200 行 jQuery 代碼的功能完全取代。
杜芬宅同意那並不是全部情況
底線是:在解決問題的過程中,首先“Think in AngularJS”(以AnguarJS的方式去思考問題去解決);如果你想不到解決方案,請求助於社群;如果在嘗試了所有這些方法之後還找不到簡單的解決方案,然後再求助於jQuery。但是,絕對不要依賴jQuery,否則你永遠無法真正掌握AngularJS。
之後有點長氣,想深入了解請自行查閱。
杜芬宅反而想說說下圖︰
Data Binding in Classical Template Systems
Most templating systems bind data in only one direction: they merge template and model components together into a view. After the merge occurs, changes to the model or related sections of the view are NOT automatically reflected in the view. Worse, any changes that the user makes to the view are not reflected in the model. This means that the developer has to write code that constantly syncs the view with the model and the model with the view.
在杜宅芬從前某個開發項目中,
Template 是一些HTML,Model是PHP,View是Browser的結果
HTML 的web page透過ajax call PHP,return的可能是XML / JSON,再用 jQuery 分拆return 的東東顯示出來
往往在合併後,可能資料經使用者有改動,同時又要傳回server。
便要再編寫另一段程式,取回值(例如︰$("#dataContainer").val()) ,
再併湊一起送出。
如果PHP 傳回的值會不時變改,可能就要定時定侯再去抓一次DATA
Data Binding in Angular Templates
Angular templates work differently. First the template (which is the uncompiled HTML along with any additional markup or directives) is compiled on the browser. The compilation step produces a live view. Any changes to the view are immediately reflected in the model, and any changes in the model are propagated to the view. The model is the single-source-of-truth for the application state, greatly simplifying the programming model for the developer. You can think of the view as simply an instant projection of your model. Because the view is just a projection of the model, the controller is completely separated from the view and unaware of it. This makes testing a snap because it is easy to test your controller in isolation without the view and the related DOM/browser dependency.
Template 是一些HTML,Model是Javascript(不,正確來說應該是AngularJS),View是Browser的結果
Angular templates有點不同,在 Browser 上 compile 後,任何view上的變動都會對Model有影響,
同時 Model 有變更亦會在View上自動反影出來。
那就是 Angular 經常強調,很自豪的 Two-way Data Binding (雙向的資料綁定),那令我想起已經被遺棄的
knockout,也有幾分相似
自說自話
回到那個部份,杜芬宅認為 AngularJS 是另一個層次的東西,不能單純地和 jQuery 作比較。
我們看看官方的自白
AngluarJS
What is AngluarJS (https://docs.angularjs.org/guide/introduction)
AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML's syntax to express your application's components clearly and succinctly. Angular's data binding and dependency injection eliminate much of the code you would otherwise have to write. And it all happens within the browser, making it an ideal partner with any server technology.
jQuery
What is jQuery? (http://jquery.com/)
jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.
http://try.jquery.com/levels/1/sections/2
jQuery 正如 LOGO 的口號一樣,write less, do more (http://brand.jquery.org/logos/)
jQuery 的宗旨是 一件很複雜的事情只需很少的編碼 就可以完成,
一個最簡單的例子,假設要 Point to / get 一個 Element
var elementObject = document.getElementById("elementID");
var elementObject = $("#elementID");
後續例子
真的是少了,我沒有騙你
/* Javascript version */
function getValue(){var x=document.getElementById("myHeader");alert(x.innerHTML)}
/* jQuery version */
$(function(){$("#elementID").click(function(){alert($(this).text())})});
還可以除去 onclick="getValue()",共節省29字元。
AngluarJS 是為著 動態 web apps 設計出來, web apps即是任何在瀏覽器上執行的程式。
不單單是資訊性的網頁,一個網頁遊戲可以算是一個Web app,一個網上聊天室可以說是一個Web app。
詳見 web app 定義
http://en.wikipedia.org/wiki/Web_application
http://webtrends.about.com/od/webapplications/a/web_application.htm
AngluarJS 以 HTML 為範本,其後使用者可自行 擴展更多的 HTML tags去製作你的 web apps。
令結構較加清晰簡潔,那個概念與 HTML5 有相似之處。
AngluarJS 同樣地能夠實現使用者自定義更多的 HTML 語法。
讓開發一個項目時結構得到規範,那與片中對 HTML5 的比喻有著異曲同工之妙。00:27 至 01:21
雖然 XHTML 同樣可以自定義語法,不過 AngluarJS 還伴隨了 Data binding 令功能可以更擴泛應用。
AngluarJS 的 data binding 和 dependency injection (那個未爬文不知是啥),能夠為開發者節省更多 Coding ,因為 AngluarJS 幫你處理了。
最後 AngluarJS 是在瀏覽器執行,不論背後伺服器的種類、建構技術都不受影響。
jQuery VS AngularJS
Compare functional requirement implementation
Function - Get the district (last part of the address)
A friendly behavior pops from my mind at once, I would not accept the user need to press a [confirm] button to let the program know that he/she just type/pase a list of addresses.
Because I'm that user, I would not like to click more one time so that I choose to coding more to handle this one.
The keyup event is sent to an element when the user releases a key on the keyboard.
The
change
event is sent to an element when its value changes. This event is limited to
<input>
elements,
<textarea>
boxes and
<select>
elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.
I use keyup to capture the keyboard action, I use change to handle the user paste content by mouse right click.
There was a limitation, the change only affects when the textarea loses focus, but still better than nothing.
用 jQuery 的 change 就可以每當Textarea內容變更時獨發,
用 jQuery 的 keyup 就可以當在Textarea時每逢有鍵盤放開按鍵時獨發,
用 keyup 持續監視鍵盤輸入, change 則是修補 如果只用 滑鼠貼上而沒有 keyup的狀況。
不過 change 用在textarea上必須out focus才有效果。
即是滑鼠貼上也要按其它地方/按TAB,總之要離開Textarea才有效果,有點美中不足。
首先建立一個Controller,用 model 和 bind 將資料綁定到兩個Textarea。
顯示地址最尾部份的使用一個format / filte,便可以對地址進行一些處理再顯示出來。
/* jQuery version */
$("#client-address").keyup(function () {
var form = $(this).parents(".formEntry");
form = form.find("#client-address").val();
aKeyhWasType(form);
});
$("#client-address").change(function () {
var form = $(this).parents(".formEntry");
form = form.find("#client-address").val();
aKeyhWasType(form);
});
function aKeyhWasType(form) {
console.log(arguments.callee.name + " function start");
getTheSubstring(form);
}
function getTheSubstring(text){
text = text.trim();
$("#custom-area-code-td").text("");
$("#address-substring").val("");
textInLine = text.split("\n");
for(i=0; i < textInLine.length; i++){
commaIndex = textInLine[i].lastIndexOf(",");
var addressLastLine = textInLine[i].substring(commaIndex+1, textInLine[i].length);
addressLastLine = addressLastLine.trim();
$("#address-substring").val($("#address-substring").val()+addressLastLine+"\n");
}
});
/* AngulgarJS version */
// Controller customAddress
app.controller("customAddress", function($scope){
$scope.customAddressText = "";
});
// split the customAddress,
// filter the last part address
app.filter('getAddressLastPart', function(CustomAddressLastPart) {
return function(input) {
// do some bounds checking here to ensure it has that index
textInLine = input.split('\n');
var _customAddressLastPart = "";
for(i=0; i < textInLine.length; i++){
commaIndex = textInLine[i].lastIndexOf(",");
var addressLastLine = textInLine[i].substring(commaIndex+1, textInLine[i].length);
addressLastLine = addressLastLine.trim();
if(!addressLastLine)
continue;
_customAddressLastPart += addressLastLine + "\n";
}
_customAddressLastPart = _customAddressLastPart.trim();
CustomAddressLastPart.setAddressList(_customAddressLastPart);
return _customAddressLastPart;
}
});
Function - Generate the customer area code UI
When the program getting each last part of the address, the last part will compare with the dictionary to try to matching a area code.
There was a DIV template hidden in the HTML code. Although jQuery allow create DOM, I wont put it in HTML in develop status.
clone
means copy a UI template, which is include a textbox, selection box and one more textbox.
Put the address last part into first textbox, assign the matched area code to the last textbox if found.
appendTo
the page, finally assign the matched area code to the selection box, because the
change
action only can affect to DOM, the change action must after the
appendTo
.
If the matched area code found, lock the selection box and textbox.
Hopes that reduce the items keep your focus.
After process all the last part address
Set the lock/unlock button behavior,
as above said that the program will lock the block if that last part address found, we need to provide a Undo to unlock the block if the program making misjudgment. Relatively, I give you lock again=.= hahaha.
add change trigger on selection box, last textbox, update the Area code identification textarea when the use change or assign the area code.
the trigger include to sync between the selection box and last textbox.
Finally, clear and refresh the Area code identification textarea.
At as current, some of last part address may be matched in dictionary, we found all the area code and paste on the Area code identification panel.
在分割每段地址最後部份時,會與 字典進行比對。
比對後會用
clone
複製出一個框框,框框已隱藏在網頁內。
將地址最後部份、比對成功的代表 香港、九龍、新界、離島的字元 放進框框內、以及選取適當的下拉選項。
由於jQuery change只可以控制DOM,所以必須要將框框複製品 嵌入到網頁內。
然後再進行選取選單的動作。
本來原意是想減少用家需要關注的項目,如果成功從字典找到地址。
會自動鎖著整個框框,你不用擔心會誤改了地區。
不過為了讓人悔旗所以給你解鎖
為框框內用家可以改動的內容都加入觸發器,每有改動內容就觸發。
更新一次在 Area code identification 文字方塊內顯示的 area code。
一個網站 / 一個網頁 如果需要與使用者大量的互動, AngularJS 將會是你開發的 希望之光。
依靠著 AngularJS 的 Two-way Data Binding