2013年6月22日 星期六

[Javascript]knockout.js - 資料處理-清單呈現方式

在第一篇有提到如果你的Web應用主要再處理一些CRUD,那很適合用knockout.js來實現MVVM架構,後續介紹了屬性、事件的控制,這篇就要來介紹在knoctout.js對於資料的顯示及處理。

foreach

foreach可以綁定一組Array資料,只要很簡潔的程式碼,就能輕鬆的完成多筆顯示的功能,

首先,我們定義一個使用者的class,包含他的序號、姓名

image

再來到ViewMode去繫結這個User的陣列資料,而給值的方式跟以往不一樣,observableArray()主要用來繫結陣列,如果你這個陣列資料有任何變動,如新增、刪除,他會自動同步到UI的顯示。

image

接著我們新增假資料,讓頁面載入就有三筆資料

image

HTML部分才是強大的地方!只要用以下指定方式即可!

Table 呈現方式:

image

清單呈現方式:

image

接著我們加入新增和移除的功能,程式很單純,可往下看完整程式碼應該很好懂,要特別注意的是,如果我們要針對某列做處理,可以用$parent這個參數來取得父元素,如下圖,在某列點選移除,取得該列的TR,則可針對這筆TR做處理:

image

除了$parent外,還有以下方式:

$parents – 抓取所有外部的元素 ex :

$parents[0] - 此元素的父類別,以此例來說即為 TR (等同於$parent)

$parents[1] - 此元素的父類別的父類別(好饒舌),以此例來說即為 tbody …以此類推

$root - 抓取最外層的元素,以此例來說即為 body ,(等同於$parents[$parents.length-1])

以下附上新增&刪除的完整程式碼:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="Scripts/jquery-1.7.2.min.js"></script>
<script src="Scripts/knockout-2.1.0.debug.js"></script>
</head>
<body>
<button data-bind="click: AddUser">Add</button>
<button id="btn_json">Json</button>
<fieldset>
<legend>Table 呈現</legend>
<table>
<thead>
<tr>
<th>Number</th>
<th>First name</th>
<th>Last name</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: users">
<tr>
<td data-bind="text: Index"></td>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
<td>
<button data-bind="click: $parent.RemoveUser">移除</button>
</td>
</tr>
</tbody>
</table>
</fieldset>
<fieldset>
<legend>清單呈現</legend>
<ul data-bind="foreach: users">
<li>
<span data-bind="text: Index">:</span>
<span data-bind="text: firstName"></span>
<span data-bind="text: lastName"></span>
<button data-bind="click: $parent.RemoveUser">移除</button>
</li>
</ul>
</fieldset>

<script type="text/javascript">

//定義使用者
var User = function (Index, firstName, lastName) {
var self = this;
self.Index = Index;
self.firstName = firstName;
self.lastName = lastName;
}

//ViewModel
var viewModel = function () {
var self = this;
self.users = ko.observableArray();
//新增使用者事件
self.AddUser = function () {
var index = self.users().length + 1;
model.users.push(new User(index, "Kyle", "Shen" + index));
}
//移除使用者事件
self.RemoveUser = function () {
self.users.remove(this);
}
}

//手動新增3筆假資料
var model = new viewModel();
for (var i = 1; i <= 3; i++) {
model.users.push(new User(i, "Kyle", "Shen" + i));
}
ko.applyBindings(model);

</script>
</body>
</html>


執行結果圖



image



--
Reference
http://knockoutjs.com/documentation/introduction.html
--



關聯文章



  • [Javascript]knockout.js-初體驗

  • [Javascript]knockout.js - 關於Html屬性的控制

  • [Javascript]knockout.js - 事件處理

  • [Javascript]knockout.js - 資料處理-清單呈現方式



  • 2013年6月21日 星期五

    [Javascript]knockout.js - 事件處理

    這篇要介紹一些寫Web常用的事件,在上面兩篇範例,我們已經有使用到click、checked…等等的事件,這篇主要將其他常用的事件做個介紹,並如何在knockout.js實現。

    mouseover、mouseout、disable、enable事件

    這是很常見的應用,控制滑鼠移入跟移出時做一些事情,此例情境:在移入表單時highlight這個區塊(更改背景顏色),如果他是女生,則讓她填寫電話,並且不讓她點離開(寫程式寫到瘋了…)

    image

    disable和enable我都指向ViewModel的LeavePhone這個自定義的Value,但true和false執行其實是相反的,就在自己習慣怎麼應用。

    focus事件

    focus是很常會用到的事件,我們在加入兩個需求:

    點選姓名時,則變成編輯狀態,而失去焦點時,則變更為Lable(單純顯示)的狀態。

    image

    如果電話欄位有焦點時,則跳出電話格式的提醒文字

    image

    Submit事件

    在送出表單之前,通常會有一些資料驗證,如果沒問題後才送回後端,在knockout.js,一樣只要在form標籤裡面bind一個function即可,當然妳也可以使用Click來觸發表單的Submit,但Submit通常多了一些行為,ex 點選Enter時送出表單,如果妳指定為click,還要針對輸入Enter事件做處理。

    完整程式碼:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="Scripts/knockout-2.1.0.debug.js"></script>
    </head>
    <body>
    <form data-bind="submit: CheckData">
    <div>
    <fieldset data-bind="event: { mouseover: Over, mouseout: Out }, style: { 'background': BackColor }">
    <legend>輸入表單
    <button type="submit" data-bind="disable: LeavePhone">離開</button></legend>
    <div>
    姓名:
    <lable data-bind="visible: !editing(), text: name, click: edit"></lable>
    <input data-bind="visible: editing, value: name, hasfocus: editing" />
    </div>
    <em>點選可修改姓名</em>
    <div>
    <input type="checkbox" data-bind="checked: LeavePhone" />我是女生<br />
    電話:
    <input type="text" data-bind="value: PhoneNumber, enable: LeavePhone, hasfocus: IsFocus" />
    <span data-bind="visible: IsFocus">請輸入格式09XX-XXXXXX</span>
    </div>
    <button type="submit">送出表單</button>
    </fieldset>
    </div>
    </form>
    <script type="text/javascript">
    var viewModel = function () {
    var self = this;
    self.BackColor = ko.observable(""); //區塊背景顏色
    self.LeavePhone = ko.observable(false);//是否需填寫電話
    self.PhoneNumber = ko.observable("");//電話
    self.IsFocus = ko.observable(false);
    self.name = ko.observable("路人甲");
    self.editing = ko.observable(false);
    this.edit = function () { this.editing(true) }
    //滑鼠移入事件,更改背景顏色
    self.Over = function () {
    self.BackColor("#eef3a8");
    },
    //滑鼠移初事件,無背景顏色
    self.Out = function () {
    self.BackColor("");
    }

    self.CheckData = function () {
    //驗證表單各欄位是否正確..在此省略
    return confirm("是否確定要送出表單?");
    }
    };
    ko.applyBindings(new viewModel());
    </script>
    </body>
    </html>
    --

    --
    Reference
    http://knockoutjs.com/documentation/introduction.html
    --



    關聯文章



  • [Javascript]knockout.js-初體驗

  • [Javascript]knockout.js - 關於Html屬性的控制

  • [Javascript]knockout.js - 事件處理

  • [Javascript]knockout.js - 資料處理-清單呈現方式

  • 2013年6月16日 星期日

    [Javascript]knockout.js - 關於Html屬性的控制

    在上一篇knockout.js初體驗有介紹用此框架來實作前端MVVM架構,延續這個主題,今天主要介紹控制常用Html屬性的幾個用法。

    Visible Binding

    在以往要控制Html標籤的顯示隱藏,我們可能需要在DOM的事件判斷將該標籤隱藏,如點選Checkbox,顯示某textarea。

    image_thumb2

    CSS Binding


    而CSS一樣可以加入一些邏輯判斷,套用不同的css,我們再將checkbox屬性打勾時(ShowTextarea),套用一個.highlight css class

    <h3 data-bind="css: { 'highlight': ShowTextarea }">Visible Binding</h3>


    Style Binding



    除了指定CSS外,也可使用Style來指定CSS屬性,方便的是可以做一些style的邏輯判斷,如我們判斷瀏覽器為Chome的話就加上底線的style



    特別要注意的是,在CSS屬性有"-"符號,如text-Decoration在knockout.js需寫成textDecoration



    Attr Binding



    有寫過JQuery的人一定對attr不陌生,在attr() function,我們通常用來設置Html標籤的屬性值,如$('#hrefID’).attr(‘href’,'http:www.google.com.tw’)就是將ID為hrefID的href屬性改變為Google網址,而在Knockout.js,我們一樣可以用Binding的方式來實現,之所以把Attr放在最後介紹,因為是一個很彈性的function,像Jquery一樣,你可在Attr指定Visible、Disabled、Style等屬性。


     


    完整程式碼


    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="Scripts/jquery-1.7.2.min.js"></script>
    <script src="Scripts/knockout-2.1.0.debug.js"></script>
    <script type="text/javascript">
    //判斷是否為Chome瀏覽器
    var IsChome = function () {
    if (navigator.userAgent.indexOf('Chrome') != -1) {
    return true;
    }
    return false;
    };

    var viewModel = function () {
    //定義ShowTextarea,預設值為隱藏textarea
    var self = this;
    self.ShowTextarea = ko.observable(false);
    self.AreaData = ko.observable("");
    //定義<a></a>相關的ViewModel
    self.HrefLink = ko.observable("http://www.google.com.tw");
    self.HrefTitle = ko.observable("Google Now");
    self.HrefText = ko.observable("Go to the Google");
    self.HrefType = ko.observable("_blank");

    //ViewModel增加確認瀏覽器
    self.CheckBroser = ko.computed(function () {
    return IsChome() ? 'underline' : '';
    });
    };

    $(function () {
    ko.applyBindings(new viewModel());
    });
    </script>
    <style type="text/css">
    .highlight {
    color: blue;
    }
    </style>
    </head>
    <body>
    <h3 data-bind="css: { 'highlight': ShowTextarea }" >Visible Binding</h3>
    <!-- checked值改變時,去變更ViewModel的ShowTextarea true or false-->
    <input type="checkbox" data-bind="checked: ShowTextarea" />顯示textarea
    <br />
    <!-- 繫結ViewModel的ShowTextarea來控制顯示或隱藏-->
    <textarea rows="4" cols="50" data-bind="visible: ShowTextarea">
    </textarea>
    <h3 data-bind="style: { 'textDecoration': CheckBroser }" >Attr Binding</h3>
    <!-- 繫結此<a></a>對應ViewModel的欄位,設置title屬性即時獲得變化 -->
    Set Title :
    <input type="text" data-bind="value: HrefTitle" /><br />
    <a data-bind="text: HrefText, attr: { 'title': HrefTitle, 'href': HrefLink, 'target': HrefType }"></a>

    </body>
    </html>


    --
    Reference
    http://knockoutjs.com/documentation/introduction.html
    --


    關聯文章


  • [Javascript]knockout.js-初體驗
  • [Javascript]knockout.js - 關於Html屬性的控制
  • [Javascript]knockout.js - 事件處理
  • [Javascript]knockout.js - 資料處理-1
  • 2013年6月9日 星期日

    [Javascript]knockout.js-初體驗

    前言

    活在這代的程式設計師很幸福,網路資源非常多,且不管Server-Side或者是Client-Side的程式語言,已經越來越多的函式庫能使用,只要簡單的語法就能實現複雜功能,前一陣子開始尋找JavaScript的框架,無意間看到黑暗執行緒前輩撰寫的knockout.js系列文,就決定開始利用時間好好的Study這個Javascript框架,但光看是沒有用的,就好像女生不跟著鄭多燕老師動一動的話永遠也瘦不下來!廢話不多說,這篇主要做個簡單介紹。

    MVVM

    如果你Web應用主要在處理一些資料的CRUD,knockout.js是你可考慮的前端框架,他主要在頁面上實現MVVM(Model-View-ViewModel)開發架構,將資料及事件定義成一個ViewModel,用來做雙向的綁定(Two-Way Binding),以實例加下圖來解釋:

    如使用者在某個text欄位輸入資料或者點選某個Button,會造成資料的變動,在以往我們可能需要在這些事件(onChange、onKeyup)來控制顯示的資料,而knockout.js幫我們簡化了這些工作,將這些Event及及Data定義在一個ViewModel的Class,當有變動或觸發時,由於View和ViewModel的資料是雙向綁定的,所以使用者輸入的資料能被ViewModel捉捕,而ViewModel的資料更新也能自動反應在View上,這樣的好處是我們可以專注在資料的操作,無需去管HTML的細節。

    所以我想這就是命名為 Knock(敲) - Out的原因吧XD

    圖片來源

    knockout.js的特性

    1.當資料模組異動時,自動反應到UI該更新的部分

    2.連結欄位的方式語法非常簡單,有點像是ASP.NET的GridView+DataSource

    3.高彈性的樣本可套用,建構複雜UI非常方便

    4.一樣可使用JQuery(本人對JQuery控制DOM還有愛,能不衝突真是太棒了)

    5.微軟主推!故在MVC的SPA(Single Page Application)專案可看到就是以knockout.js來實作

    6.支援各瀏覽器

    如何開始

    就小弟學習方式,除了看黑暗大的系列文外,可去官網Step by step的教學,另還有提供Sample Code,故大大的減少了學習曲線,另外這邊有個Google論壇,會有人很多人在上面討論(但都是英文就是了),也可去Youtube下關鍵字,會看到很多教學影片。

    開始動一動

    需求情境

    這篇要寫的功能非常無聊,輸入員工的姓氏及名字,然後用一個<h1>標籤即時顯示已姓加名的公司Email,點選Button能Alert此Mail,希望能Step by step來簡單說明。

    定義一個ViewModel

    在開始動手前,先別管HTML的UI吧,先定義出此頁面所需的資料,定義出這個ViewModel,在此功能,我們在Model有FirstName及LastName及Email三個資料欄位,而預設值給空白字串。observable()是knockout.js給Value的語法,切記不要寫成Self.firstName = “”,而computed()語法可將其他欄位進行運算,以此案例,我們希望將姓氏和名字組成Email然後回傳。

    <script>
    //先定義一個員工的ViewModel
    var StaffModel = function () {
    var Self = this;
    Self.firstName = ko.observable("");
    Self.lastName = ko.observable("");

    Self.Email = ko.computed(function () {
    if (Self.firstName() == "" || Self.lastName() == "") return "";
    return Self.firstName() + "." + Self.lastName() + "@gmail.com";
    }, Self);

    };
    </script>


    而HTML的部分只要簡單的Data-bind語法,輸入對應的欄位名稱即可完成雙向綁定,而text和Value就等於HTML的標籤屬性。

    <input type="text" id="txt_fname" data-bind="value: firstName" placeholder="ex:Kyle" />
    <input type="text" id="txt_lname" data-bind="value: lastName" placeholder="ex:Shen" />
    <h1 data-bind="text: Email"></h1>
    增加Click 事件

    接著我們在ViewModel再來定義Click事件,點選之後秀出Email

    //Click事件
    Self.AlertEmailValue = function () {
    if (Self.firstName() == "" || Self.lastName() == "") {
    alert('請輸入完整資訊!');
    return;
    }
    var Email = Self.firstName() + "." + Self.lastName() + "@gmail.com";
    alert('Hello,Your Email is ' + Email);
    };
    而Event的Binding方式也很簡單:
    <button data-bind="click: AlertEmailValue">秀出Email</button>
    完成綁定最後,只要利用applyBindings()語法,即可將這個頁面完成雙向綁定,此段須放在JQuery的$.ready裡面,確保元素都載入完成
    $(function () {
    ko.applyBindings(new StaffModel());
    });


    完成效果



    是不是很Cool呢!!再以往我們可能要用Script去控制DOM完成效果,現在套用knockout.js已經省了很多事~1

    後記

    其實小弟學習knockout.js最主要希望能搭配MVC的SPA網頁來進行開發,所以決定循序漸進的一步一步學習,順便在這學習過程中,記錄下來,能幫助到一些人,如果內容敘述有錯,請麻煩告知小弟,會盡快做處理 ^_^



    範例檔下載



    --



    Reference



    http://sushiwens.blogspot.tw/2012/07/backbonejs-angularjs-emberjs-knockoutjs.html



    http://blog.miniasp.com/post/2013/04/24/Front-end-Engineering-Fineart-An-Introduction-to-AngularJS.aspx



    http://blog.darkthread.net/post-2012-05-09-knockout-js-intro.aspx



    http://learn.knockoutjs.com/#/?tutorial=collections


    關聯文章


  • [Javascript]knockout.js-初體驗
  • [Javascript]knockout.js - 關於Html屬性的控制
  • [Javascript]knockout.js - 事件處理
  • [Javascript]knockout.js - 資料處理-1