Knockoutjs官網翻譯系列(一)

? ? ? ?最近馬上要開始一個新項目的研發,作為第一次mvvm應用的嘗試,我決定使用knockoutjs框架。作為學習的開始就從官網的Document翻譯開始吧,這樣會增加印象并加入自己的思考,說是翻譯也并不是純粹的翻譯,會加入自己對知識點的思考以及自己的嘗試,在系列最后也希望用一個應用案例作為結尾。希望自己能堅持下來并有所收獲,理解不對的地方大家也指出來避免我”誤入歧途“。也并不會翻譯所有的內容,我會根據自己的經驗選擇最能反映它使用和精髓的部分。當前版本為3.4

? ? ? 好了,閑言少敘,正篇開始。

  

  ===================================華麗的分割線============================================

? ? ? knocket主要圍繞由以下三個核心特征組成:

  1. ?Observables(觀察器)與dependency tracking依賴追蹤)
  2. ?Declarative bindings(聲明式綁定)
  3. ?Templating(模板)

? ? ??

? ? ?MVVM and View Models

? ? ??Model-View-View Model (MVVM)?是一種創建用戶界面或用戶接口的設計模式。你可以通過將UI拆分成下面三個部分從而將復雜的UI簡潔化,清晰化:

  • Model(數據模型): 應用程序存儲數據。模型包括了你應用程序域中與業務相關的數據以及這些數據對應的操作(例如 一個銀行賬戶模型具有轉賬的功能)并且它跟UI是相互獨立 的。 當時用KO的時候,通常這類模型是通過ajax從服務器端進行獲取的。
  • ViewModel(視圖模型): 服務于數據模型,為數據模型在UI上的展現及UI上的操作進行包裝服務。 例如, 如果你要在UI上做一個列表展現, 你的視圖模型將會是包含一個數據集合的對象, 并提供一些添加和刪除數據的相關方法。需要注意的是視圖模型并不是UI本身,它并不包括任何UI元素,比如按鈕啊,標簽啊樣式之類。它也不是持久化的數據對象,它只是為數據模型臨時保存一些用戶正在處理的數據。當我們在使用KO的時候,它無非就是一些純粹的javascript對象而已。
  • A?view(視圖): 一個可視,可交互的真正的UI展現,他展現著視圖模型的當前狀態。它所展現的信息來自于視圖模型,并且向視圖模型發送命令執行動作 (例如: 當用戶點擊按鈕的時候,視圖向視圖模型發送命令,視圖模型進行真正的操作),并且當視圖模型屬性發生變化的時候,視圖會自動進行展現的更新。當時用KO的時候,你的視圖中的Html元素內容可以通過聲明式綁定與視圖模型進行連接從而決定UI如何展現。另外,你也可以通過使用模板的方式來使用視圖模型中的數據生成UI中的Html內容。(模板后面會提到)

? ? ? 好了,讓我們來舉個很小的例子來看看上面說的視圖與視圖模型在KO中是如何協作的。創建一個視圖模型對象非常容易,隨意聲明一個javascript對象我們就可以將它作為視圖模型對象。例如:

 //創建一個視圖模型對象
var myViewModel = {personName: 'Bob',personAge: 123};
ko.applyBindings(myViewModel);//ko是knockoutjs中的全局對象,這句話的意思是將數據模型對象與UI中所有有data-bind的屬性進行聲明綁定的元素進行連接

然后我們就可以創建一個非常簡單的視圖來展現上面的視圖對象。還記得嗎?他們使用聲明式綁定來進行連接。下面的視圖用來展現視圖模型對象中的personName數據。

The name is <span data-bind="text: personName"></span>

?

好了現在如果運行頁面的話將會顯示如下運行結果:

通過上面的例子我們可以看到,在UI上賦值我們并沒有像jquery一樣通過js來控制,而是使用聲明綁定的方式在UI元素和js數據對象上建立聯系,自動展現。在上面的代碼標簽中data-bind?并不是Html中的原生標記,它在Html5中得到瀏覽器的支持,是KO框架用來進行聲明式綁定的工具,所以在KO中進行聲明式綁定,都通過data-bind屬性進行。有了視圖模型,有了相應視圖,最后要進行兩者的連接了,所以下面這行代碼必不可少:

ko.applyBindings(myViewModel); //將myViewModel對象與UI中所有進行了聲明式綁定的元素進行連接,注意:是所有。

完整測試代碼:

The name is <span data-bind="text: personName"></span>
@section scripts
{<script src="~/Scripts/knockout-3.4.0.js"></script><script type="text/javascript">$(function () {var myViewModel = {personName: 'Bob',personAge: 123};ko.applyBindings(myViewModel);});</script>
}

?

? ? ? 關于ko.appyBindings(myViewModel)中參數的作用說明一下:第一個參數說明在整個UI中你希望使用哪個視圖模型對象與視圖中的聲明綁定進行連接。你也可以傳遞第二個參數來決定這個視圖模型與UI中的哪個特定的聲明式綁定(data-bind)進行連接,而不是與所有的進行連接。舉個例子,?ko.applyBindings(myViewModel, document.getElementById('someElementId'))。這就限制了這個視圖模型對象只能與ID為someElementId?的Html元素對象以及它的后代元素對象進行連接,這樣的話當你想要定義多個視圖模型對象并且與頁面中不同的元素進行綁定的時候就會特別有用。到目前為止真的是相當簡單吧。

? ? ?Observables

? ? ?好了,你已經看到了如何創建一個基本的視圖模型以及如何通過綁定進行它的屬性數據的展現。但是使用KO一個核心的好處是當視圖模型內容改變的時候它還會自動更新你的UI,反之亦然。這有時會大大簡化你的代碼(我們稍后展示這個效果)。那么KO如何知道你的視圖模型什么時候發生了改變進而更新你的UI呢?答案是:你需要將你的數圖模型中的屬性聲明為observable類型對象。 observables類型對象非常特殊,當視圖模型發生改變的時候,他們可以向訂閱者發出通知,并自動建立與訂閱者的關系,訂閱者也就是具有聲明式綁定的元素。舉個例子, 重寫一下上面的代碼如下:

? ??

$(function () {var myViewModel = {personName: ko.observable('Bob'),personAge: ko.observable(123)};ko.applyBindings(myViewModel);});

? ? ?現在,你完全不需要視圖 data-bind?聲明部分保持不變. 與之前代碼不同的是,現在ko可以自動監測變化了, 一旦視圖模型有數據發生變化,它就會自動更新視圖。

? ? ?Observables屬性的讀取與寫入

? ?? 要讀取observable的當前值,只需要像調用方法一樣以無參數的方式調用它。以上面的代碼為例,?myViewModel.personName()?將會返回?'Bob',而myViewModel.personAge()?將返回123。

? ? ?要向observable屬性中寫入一個值的話也跟上面一樣進行調用,只不過傳入一個你想要寫入的新值就可以了。舉個例子:調用myViewModel.personName('Mary')?將會為personName賦一個新的名字。另外KO還提供了一個非常方便的代碼鏈寫法。?像這樣:myViewModel.personName('Mary').personAge(50)?會修改personName為?'Mary'?,personAge修改為?50。

? ? ?observables的核心作用就是"觀察" ,也就是說, 被聲明為observable的屬性將來是會被雙向通知的,它通知其它UI元素它已經被修改了,并且觀察相關UI元素內容,并將變化值更新到ViewModel對象上。KO框架中的很多內置綁定就是用來干這事兒的。所以,當你在UI元素上(例如span標簽)寫上data-bind="text: personName"的時候?text?綁定類型將把這個span元素進行注冊并做好被通知的準備只要視圖對象上的personName發生了該表,span就會被通知修改內部的文本內容(假設personName是一個observable值,另外除了text綁定還有許多其它類型綁定,我們后面提到)。

? ? ?當你通過調用myViewModel.personName('Mary')來修改personName的值的時候, text綁定將會自動更新相關DOM元素的text內容?。

? ?observables的顯示訂閱處理??

? ? 通常你無需干預訂閱的過程,所以初學者可以暫時跳過這一小節。

? ? 當observable類型數據發生改變后如果你希望在這個過程中做一些處理,你可以調用observable屬性上的subscribe方法來將自己的處理代碼注冊進來。舉個例子:

myViewModel.personName.subscribe(function(newValue) {alert("The person's new name is " + newValue);
});

? ? 上面這段代碼執行后,如果修改了personName的值后,那么將會彈出一個警告框,并且通過newValue參數可以獲取當前正在更新的值。這個過程叫訂閱注冊。

? ??subscribe方法接受三個傳入參數:?callback?是一個function當通知到來時會自動執行,?target?(可選) 定義了在callback方法中?this代表了哪個對象(默認的話this就是當前視圖模型對象), event(可選; 默認值是"change") 事件名稱,是指當什么類型的事件發生的時候會有通知到來,默認情況下就是當值發生改變的時候。(其它類型我們后面談到)。

? ? ?當然了,一旦你注冊了一個自己的訂閱,你也可以根據需要在未來的某個時候取消這個訂閱,你需要先定義一個變量來接收subscribe當前的返回值,然后調用dispose方法。代碼如下

var subscription = myViewModel.personName.subscribe(function (newValue) { /* do stuff */ });
// ...then later...
subscription.dispose();

? ? ?如果你希望在observable類型值在發生改變,但被賦值之前做一些處理的話,你也可以在beforeChange?事件上注冊自己的處理,代碼如下:

myViewModel.personName.subscribe(function(oldValue) {alert("The person's previous name is " + oldValue);
}, null, "beforeChange");

? ? 注意: Knockout 是否觸發上面的訂閱還有一個默認條件就是新的值必須與老的值不相同,如果賦值時是相同值的話那么將不會觸發這兩個訂閱。如果需要更改這種默認動作可以使用訂閱器上的extend方法來修改。代碼如下:

myViewModel.personName.extend({ notify: 'always' });

? ? 最后,如果你的observable屬性在更新時的動作比較耗時或者會更新的很頻繁,你可以通過限制通知的時間間隔,畢竟訂閱通知會有性能影響。做法如下:

myViewModel.personName.extend({ rateLimit: 50 });

? ? 這樣的話就算是頻繁更新屬性值,每次通知的事件間隔也會控制在50毫秒。測試代碼如下:

<button type="button" id="btnStart">點擊測試</button>
<span id="clickcontent"></span>
@section scripts {<script src="~/Scripts/knockout-3.4.0.js"></script><script type="text/javascript">$(function () {var myViewModel = {//personName: ko.observable("ZhouBo")
                personName: ko.observable("ZhouBo")};myViewModel.personName.extend({ notify: 'always' });myViewModel.personName.extend({ rateLimit: 5000 });ko.applyBindings(myViewModel);var index = 0;$('#btnStart').click(function () {$('#clickcontent').text(++index);myViewModel.personName(++index);});});

說明:如果我快速點擊按鈕 btnStart,則5秒鐘之后第一個span的內容才會發生變化,也就是5廟后才發送了一次通知。

?

轉載于:https://www.cnblogs.com/MichaelBang/p/5589421.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/395749.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395749.shtml
英文地址,請注明出處:http://en.pswp.cn/news/395749.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

無人機導航定位系統Java_無人機高精度室內定位導航的技術方案

原標題&#xff1a;無人機高精度室內定位導航的技術方案因為一些特殊的用途&#xff0c;比如室內表演&#xff0c;編隊室內飛行等&#xff0c;無人機不可避免會在室內飛行&#xff0c;無人機對室內定位精度的要求很高&#xff0c;室內空間本身就不會太大&#xff0c;若定位精度…

javascript控制臺_如何充分利用JavaScript控制臺

javascript控制臺by Darryl Pargeter達里爾帕格特(Darryl Pargeter) 如何充分利用JavaScript控制臺 (How to get the most out of the JavaScript console) One of the most basic debugging tools in JavaScript is console.log(). The console comes with several other use…

Django之靜態文件配置

靜態文件 了解靜態文件配置之前&#xff0c;我們需要知道靜態文件是什么&#xff1f; 靜態文件其實指的是像css,js&#xff0c;img等一些被模板需要的文件。 如何在Django中配置我們的靜態文件 1.建立static文件夾&#xff0c;將靜態文件放在該目錄下 2.在settings文件下配置如…

神奇的圖像處理算法

http://blog.chinaunix.net/uid-23065002-id-4392043.html http://blog.csdn.net/k_shmily/article/details/51138154 幾周前&#xff0c;我介紹了相似圖片搜索。 這是利用數學算法&#xff0c;進行高難度圖像處理的一個例子。事實上&#xff0c;圖像處理的數學算法&#xff0c…

JavaWeb項目前端規范(采用命名空間使js深度解耦合)

沒有規矩不成方圓&#xff0c;一個優秀的代碼架構不僅易于開發和維護&#xff0c;而且是一門管理與執行的藝術。 這幾年來經歷了很多項目&#xff0c;對代碼之間的強耦合及書寫不規范&#xff0c;維護性差等問題深惡痛絕。在這里&#xff0c;通過仔細分析后&#xff0c;結合自己…

java重要基礎知識點_java基礎知識點整理

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓java基礎知識點整理1.&和&&的區別&#xff1f;&&#xff1a;邏輯與(and),運算符兩邊的表達式均為true時&#xff0c;整個結果才為true。&&&#xff1a;短路與&#xff0c;如果第一個表達式為false時&#…

網易云音樂的算法有什么特點_當算法設計音樂廳時會發生什么?

網易云音樂的算法有什么特點Here are three links worth your time:這是三個值得您花費時間的鏈接&#xff1a; What happens when algorithms design a concert hall? (3 minute read) 當算法設計音樂廳時會發生什么&#xff1f; ( 閱讀3分鐘 ) How to land a top-notch tec…

開機發現超級管理員賬戶不見了

今天出現了一個怪現象&#xff0c;連接打印機的電腦上沒有超級管理員賬戶&#xff0c;只有一個剛建立的新賬戶&#xff0c;這是怎們回事來&#xff1f;噯&#xff0c;原來啊&#xff0c;安裝Windows XP時&#xff0c;如果又設置了一個管理員賬戶&#xff0c;那么系統內置沒有密…

vs自帶iis局域網調試

http://www.cnblogs.com/liluping860122/p/4685564.html轉載于:https://www.cnblogs.com/wcLT/p/5594252.html

java.util.set cannot be assigned from null_Java中有關Null的9件事

對于Java程序員來說&#xff0c;null是令人頭痛的東西。時常會受到空指針異常(NPE)的騷擾。連Java的發明者都承認這是他的一項巨大失誤。Java為什么要保留null呢&#xff1f;null出現有一段時間了&#xff0c;并且我認為Java發明者知道null與它解決的問題相比帶來了更多的麻煩&…

node.js事件驅動_了解Node.js事件驅動架構

node.js事件驅動by Samer Buna通過Samer Buna 了解Node.js事件驅動架構 (Understanding Node.js Event-Driven Architecture) Update: This article is now part of my book “Node.js Beyond The Basics”.更新&#xff1a;這篇文章現在是我的書《超越基礎的Node.js》的一部分…

如何基于 Notadd 構建 API (Laravel 寫 API)

如何基于 Notadd 構建 API Notadd 底層實現了 passport 機制&#xff0c;有統一的授權管理&#xff0c;主要支持兩種方式進行 API 授權&#xff0c;一個是 client&#xff0c;領一個是 passport&#xff0c;這個在其他文檔中有做詳細的說明。 這里主要說的是&#xff0c;如何基…

mysql 基于集_一種基于記錄集查找特定行的方法_MySQL

問&#xff1a;我的一個表中包含了名為IdValue的單列主鍵。對于給定的IdValue值&#xff0c;我希望找到緊鄰目標值之前和之后的表行(假定結果按IdValue排序)。怎樣才能不使用游標而通過一個基于集合的方法得到需要的結果&#xff1f;答&#xff1a;Transact-SQL是一個基于集合的…

react 交互_如何在React中建立動畫微交互

react 交互Microinteractions guide a user through your application. They reinforce your user experience and provide delight.微交互引導用戶完成您的應用程序。 它們可以增強您的用戶體驗并帶來愉悅感。 You may have seen some of the slick examples of microinterac…

HTTPS與MITM

HTTPS:基于SSL/TSL的HTTP協議 MITM:Man-In-The-Middle中間人攻擊 Https下中間人攻擊的思路&#xff1a; 1 去https化 2 向CA申請相似域名的證書 防范&#xff1a; 睜大雙眼轉載于:https://www.cnblogs.com/the-owl/p/5596254.html

PCB genesis自制孔點 Font字體實現方法

一.先看genesis原有Font字體 在PCB工程CAM加孔點字體要求時,通常我們直接用Geneis軟件給我們提供了2種孔點字體canned_57與canned_67,但此字體可能不能滿足各個工廠個性化需求&#xff0c;比如&#xff1a;孔密度&#xff0c;孔間距&#xff0c;孔形狀分布&#xff0c;如果有一…

Google 最新的 Fuchsia OS【科技訊息摘要】

轉自&#xff1a;http://www.cnblogs.com/pied/p/5771782.html 就是看到篇報道&#xff0c;有點好奇&#xff0c;就去FQ挖了點東西回來。 我似乎已開始就抓到了重點&#xff0c;沒錯&#xff0c;就是 LK 。 LK 是 Travis Geiselbrecht 寫的一個針對 ARM 的嵌入式操作系統&#…

java 03_Java基礎03—流程控制

流程控制參考資料&#xff1a;《Java從入門到精通》/明日科技編著. 4版. 北京&#xff1a;清華大學出版社&#xff0c;2016一、復合語句Java的復合語句由“{”開始&#xff0c;“}”結束&#xff0c;又稱為塊語句。復合語句都是由上至下被執行&#xff1b;復合語句中可以嵌套復…

這三種策略可以幫助女性在科技領域蓬勃發展

by Shubhi Asthana通過Shubhi Asthana 這三種策略可以幫助女性在科技領域蓬勃發展 (These 3 strategies can help women thrive in tech) As someone early on in her career, I’ve attended a few tech talks, conferences, and meetups. One thing I noticed is not many w…

手機衛士09_應用程序四種查看_ListView小標題_進程管理

手機衛士09_應用程序四種查看_ListView小標題_進程管理 1.懸浮窗體的功能實現: 1.1.應用程序的卸載: 包安裝器 packageInstall,包卸載packageruninstall intent.setData(Uri.pare(“package:” 應用程序包名)) 卸載完之后記得更新list集合,更新適配器. 但是不確定用戶是否點了…