欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Knockoutjs 學(xué)習(xí)系列(一)ko初體驗(yàn)

 更新時(shí)間:2016年06月07日 14:21:50   作者:茄果  
本篇主要簡(jiǎn)單介紹了knockoutjs中最重要的概念:可觀察對(duì)象(數(shù)組)。非常不錯(cuò)具有參考借鑒價(jià)值,感興趣的朋友快來(lái)圍觀吧

MVVM框架中Angular是好,但這么大而全的框架,學(xué)習(xí)難度可不低呢,上手起碼也得要個(gè)一兩周吧。而knockoutjs專注于數(shù)據(jù)綁定,只需一兩天就可以投入使用了,學(xué)習(xí)成本不要太低!在前端進(jìn)化如此迅速的時(shí)代,學(xué)習(xí)成本也是不得不考慮的一個(gè)因素。很多時(shí)候其實(shí)我們的項(xiàng)目并沒(méi)那么復(fù)雜,也并不需要萬(wàn)能的框架,更需要的反而是簡(jiǎn)單順手的工具。

Before Knockoutjs

假設(shè)我們做一個(gè)訂單系統(tǒng),需要顯示商品單價(jià),然后可以根據(jù)輸入數(shù)量計(jì)算出總價(jià)并顯示出來(lái)。使用原生代碼也很容易實(shí)現(xiàn),效果:

代碼如下:

<!--HTML code-->
Price: <span id="price"></span><br />
Account: <input type="text" id="account" value="" placeholder="請(qǐng)輸入數(shù)量" /><br />
sum: <span id="sum"></span> 
//js code
var priceNode = document.getElementById('price'),
accountNode = document.getElementById('account'),
sumNode = document.getElementById('sum'),
price = 100,
account = 11,
sum = price * account;
//初始化。
priceNode.innerText = price;
accountNode.value = account;
sumNode.textContent = sum;
//監(jiān)視 View層的用戶輸入
accountNode.addEventListener('keydown', function (e) {
window.setTimeout(function () {
account = accountNode.value;
sum = price * account;
sumNode.textContent = sum;
},10);
}); 

嗯,蠻簡(jiǎn)單的!哦,對(duì)了,我們一次展示50件商品,同時(shí)又有10類這樣的展示,還有買5盒岡本送一根油條這樣的各種促銷……

所以,你知道原生實(shí)現(xiàn)的問(wèn)題了吧:
•隨著 UI 和數(shù)據(jù)交互的增多,代碼量迅速增長(zhǎng),難以維護(hù)
•基于 Dom 查詢,id 或 class 的命名難以管理
•代碼耦合度高,難以復(fù)用

Knockoutjs簡(jiǎn)介

Knockoutjs(下面簡(jiǎn)稱ko)就是為了解決上述問(wèn)題而出現(xiàn)的,他是一個(gè)輕量級(jí)的MVVM庫(kù),專注于實(shí)現(xiàn)數(shù)據(jù)與視圖的綁定,本身并不提供 UI 類和路由等功能,上手非??臁M瑫r(shí),由于ko出來(lái)已經(jīng)有些年頭了,已經(jīng)是比較成熟的框架了。在做一些動(dòng)態(tài)顯示比較多的頁(yè)面時(shí),ko無(wú)疑是一個(gè)比較好的選擇。關(guān)于MVVM樓主就不多說(shuō)了,一圖以蔽之:

ko建立在3大核心特征之上(官網(wǎng)介紹):

1. 可觀察對(duì)象與依賴跟蹤 (Observables and dependency tracking):使用可觀察對(duì)象在模型數(shù)據(jù)之間設(shè)立隱性關(guān)系鏈,用于數(shù)據(jù)轉(zhuǎn)換和綁定。

2. 聲明式綁定 (Declarative bindings):使用簡(jiǎn)單易讀的語(yǔ)法方便地將模型數(shù)據(jù)與DOM元素綁定在一起。

3. 模板 (Templating):內(nèi)置模板引擎、為你的模型數(shù)據(jù)快速編寫復(fù)雜的 UI 展現(xiàn)。

使用ko非常簡(jiǎn)單,直接到官網(wǎng)(http://knockoutjs.com/index.html)下載并用<script>引入即可。

可觀察對(duì)象

使用ko重寫上面的例子(自定價(jià)格,這也是我小時(shí)候的愿望之一):

代碼是這樣的:

<!--HTML Code-->
<div id="one">
Price: <input type="text" data-bind="value: price" placeholder="請(qǐng)輸入單價(jià)" /><br />
Account: <input type="text" data-bind="value: account" placeholder="請(qǐng)輸入個(gè)數(shù)" /><br />
sum: <span data-bind="text: sum"></span>
</div> 
// js Code
var ViewModel = function(p, a) {
//設(shè)置為可觀察對(duì)象并以參數(shù)p、a初始化
this.price = ko.observable(p);
this.account = ko.observable(a);
//調(diào)用ko函數(shù)的時(shí)候?qū)his傳入,否則執(zhí)行ko.pureComputed內(nèi)部代碼時(shí),this為ko,ko.price()報(bào)錯(cuò)。
this.sum = ko.pureComputed(function() {
//因?yàn)榭捎^察對(duì)象是一個(gè)函數(shù)對(duì)象,所以要用 price()來(lái)讀取當(dāng)前值。
//設(shè)置值使用price(NewValue),支持鏈?zhǔn)綄懛ǎ簍his.price(12).account(3)
return this.price() * this.account();
}, this);
};
var vm = new ViewModel(135, 10);
//應(yīng)用該綁定,綁定開(kāi)始生效
ko.applyBindings(vm); 

1)先看HTML代碼:

可以看到在每個(gè)標(biāo)簽中都加入了一個(gè) data-bind = "XX:OO" 這樣的鍵-值對(duì)。這個(gè)就是 ko 的綁定語(yǔ)法,XXOO代表什么東西呢?(XXOO?樓主還是個(gè)孩子啊…)從例子可以看到XX為標(biāo)簽的屬性,可以是text、value、class、checked等標(biāo)簽屬性,其實(shí)也可以是click、focus、load等DOM事件。OO看起來(lái)像是一個(gè)變量,實(shí)際上并不是變量,而是一個(gè)函數(shù)對(duì)象,執(zhí)行這個(gè)函數(shù)(帶個(gè)())就能得到相應(yīng)的綁定值。通過(guò)XXOO就可以將元素的屬性或事件跟js中的函數(shù)對(duì)象綁定在一起(XXOO了就要相互負(fù)責(zé)哈),這就是ko的聲明式綁定。綁定的定義其實(shí)就是一個(gè)觀察者模式,只不過(guò)這是雙向的綁定,發(fā)布者和訂閱者相互訂閱了對(duì)方的消息而已,這就是MVVM的雙向綁定。ko雙向綁定的結(jié)果就是一方變化就可以自動(dòng)更新另一方,也就是通過(guò)ViewModel將數(shù)據(jù)和表現(xiàn)層緊緊綁定在一起了。綁定的效果類似于:

2)再看看js代碼:

可以看到j(luò)s中定義了一個(gè)ViewModel對(duì)象,在對(duì)象中對(duì)HTML中綁定的OO進(jìn)行了操作。這里主要有兩個(gè)操作: ko.observable()和ko.pureComputed()。

•ko.observable(p):見(jiàn)名知義、這個(gè)就是設(shè)置可觀察對(duì)象的方法,傳入的參數(shù)p就是初始化的值,這里的參數(shù)可以是基本數(shù)據(jù)類型,也可以是一個(gè)json對(duì)象。被設(shè)置為可觀察對(duì)象后就意味著系統(tǒng)會(huì)一直觀察這個(gè)值。無(wú)論是ViewModel中的p還是被綁定對(duì)象的p發(fā)生變化都會(huì)引起刷新事件,將所有用到這個(gè)值的地方都更新到最新?tīng)顟B(tài)。顯然,可觀察對(duì)象是比較消耗性能的,所以對(duì)于不需要?jiǎng)討B(tài)變更的值(如價(jià)格)則不要設(shè)置為可觀察對(duì)象,當(dāng)然還是需要放入ViewModel中進(jìn)行集中初始化。

•注意:ko.observable(p)返回的可觀察對(duì)象是一個(gè)函數(shù)對(duì)象,所以讀取可觀察對(duì)象需要使用price()這種方式;同樣的,設(shè)置可觀察對(duì)象需要使用price(newValue)這種方式。比較貼心的是,設(shè)置的時(shí)候支持鏈?zhǔn)綄懛ǎ篤iewModel.price(100).account(10)。

•ko.pureComputed()就是所謂的依賴跟蹤了,這里是單價(jià)*數(shù)量等于總價(jià),注意這里不能直接用this.sum = this.price() * this.account();來(lái)指定sum,這種寫法不能動(dòng)態(tài)刷新被綁定的對(duì)象,只是動(dòng)態(tài)改變了sum變量,但要去刷新綁定對(duì)象還需要其他操作。所以,與計(jì)算相關(guān)的綁定值都要用ko的計(jì)算函數(shù)來(lái)設(shè)置。當(dāng)然,返回的也是一個(gè)函數(shù)對(duì)象。另外,ko還有一個(gè)computed函數(shù),也可以用其來(lái)進(jìn)行設(shè)置,不過(guò)推薦使用pure的方式,以提高性能。

•注意這里的寫法:ko.pureComputed(fn, this),也就是將fn綁定到ViewModel作用域中,其實(shí)就是js中的call/apply。因?yàn)樵趫?zhí)行ko內(nèi)部函數(shù)的時(shí)候,this為ko對(duì)象,所以為了得到ViewModel對(duì)象的作用域,需要通過(guò)上面的寫法傳入this。當(dāng)然也可以在ko函數(shù)外部用that保存ViewModel對(duì)象,然后在ko函數(shù)內(nèi)部使用that來(lái)調(diào)用ViewModel對(duì)象。像這樣:

var that = this;
this.sum = ko.pureComputed(function() {
return that.price() * that.account();
}); 

定義好ViewModel構(gòu)造函數(shù)后便實(shí)例化了一個(gè)ViewModel對(duì)象,然后使用了ko.applyBindings()的方式來(lái)使得綁定生效,這一步不要漏掉了。

使用ko的頁(yè)面簡(jiǎn)單模式:

<!--HTML Code-->
<span data-bind="text: bindtext"></span> 
// js Code
var viewModel = {
bindtext: ko.observable('initValue')
};
ko.applyBindings(viewModel); 

總結(jié)起來(lái)就是:HTML中使用data-bind="XX: OO"聲明綁定,js中建立ViewModel并設(shè)置可觀察對(duì)象,最后應(yīng)用綁定。

可觀察對(duì)象數(shù)組

再看看可觀察對(duì)象數(shù)組的使用方法,在ko中可不能像js一樣數(shù)組和變量混用,對(duì)于數(shù)組對(duì)象就要用ko.observableArray([…,…])這種形式,同樣的,數(shù)組元素也可以是基本類型也可以是json對(duì)象。ko中的可觀察對(duì)象數(shù)組有一系列的數(shù)組操作方法,如slice()、sort()、push()這種,效果跟原生的js數(shù)組操作方法一樣,只是通過(guò)ko方法所做的改動(dòng)會(huì)通知到訂閱者從而刷新界面,但js方法則不會(huì)刷新界面。下面是一個(gè)簡(jiǎn)單例子:

<!--HTML Code-->
<select data-bind="options: list"></select> 
// js Code
var vm = {
// list: ko.observableArray()
list: ko.observableArray(['Luffy','Zoro','Sanji'])
};
ko.applyBindings(vm); 

關(guān)鍵點(diǎn):ko監(jiān)控的是數(shù)組的狀態(tài),而不是元素本身的狀態(tài)。也就是說(shuō)當(dāng)數(shù)組狀態(tài)變化(增減元素)的時(shí)候會(huì)觸發(fā)ko事件引起綁定對(duì)象的刷新,但數(shù)組內(nèi)部元素的變化(如:值變化)則不被監(jiān)控不能觸發(fā)ko事件。例如:


在控制臺(tái)中使用原生方法將Luffy動(dòng)態(tài)改成Lucy是不會(huì)刷新UI頁(yè)面的,而使用ko的數(shù)組操作改動(dòng)數(shù)組則會(huì)立即刷新頁(yè)面,值得注意的是在刷新的時(shí)候,也會(huì)將之前的改動(dòng)刷新出來(lái)(Luffy > Lucy)。也就是說(shuō)其實(shí)js內(nèi)存中的變量是已經(jīng)改變了,但是還缺少一個(gè)刷新DOM的動(dòng)作。這里大家可以看到,讀取數(shù)組的方法是vm.list()[0],因?yàn)閘ist也是一個(gè)函數(shù)對(duì)象,執(zhí)行返回值才是我們想要的list內(nèi)容。同理,也可以通過(guò) vm.list(["妹子","妹子","妹子"]) 這樣的方式重置可觀察對(duì)象數(shù)組,也能立即刷新UI。

如果需要將數(shù)組元素的改動(dòng)也動(dòng)態(tài)反應(yīng)到UI上,需要將數(shù)組元素也設(shè)置為可觀察對(duì)象,然后使用ko的方法改變數(shù)組元素值。注意,是使用ko的方法 list()[0]("Lucy")!


操作可觀察對(duì)象數(shù)組的方法有兩類,一類是與原生js數(shù)組方法同名的:pop, push, shift, unshift, reverse, sort, splice,這一部分與js原生方法的用法和效果都一樣,就不再贅述了。

另外一些方法是js中沒(méi)有的,主要有以下幾個(gè):

•remove(someItem) -- 刪除所有值與someItem相等的元素項(xiàng)并將它們以數(shù)組形式返回,這里的意思就是說(shuō)你可不能直接list.remove(0)來(lái)刪除第一項(xiàng),而是要用list.remove(list()[0]) 這種形式來(lái)刪除??偠灾瑐魅氲膮?shù)必須是元素項(xiàng)的值,可以用list()[0] 的形式,也可以直接輸入值的字符串(比如“Luffy”這種)。

•remove(function(item) { return item.age < 18;}) -- 刪除所有age屬性小于18的元素項(xiàng)并將它們以數(shù)組形式返回,這種用法跟平常的數(shù)組高階函數(shù)沒(méi)什么區(qū)別。Item作為高階函數(shù)的參數(shù)傳入,遍歷數(shù)組時(shí),當(dāng)高階函數(shù)返回值為真值時(shí)就刪除該項(xiàng),否則轉(zhuǎn)到下一項(xiàng)。

•removeAll(['Chad', 132, undefined]) -- 刪除所有值與 'Chad' 或 123 或 undefined 相等的元素項(xiàng)并將它們以數(shù)組形式返回。

•removeAll() -- 刪除所有項(xiàng)并以數(shù)組形式返回。

小竅門:在處理可觀察對(duì)象時(shí),若對(duì)象數(shù)量眾多而且交互頻繁的情況下,每次變更都立即刷新的話會(huì)非常消耗性能,這個(gè)時(shí)候可以使用擴(kuò)展 myObservableArray.extend({ rateLimit: 1000 }) 來(lái)設(shè)置延遲刷新。比如在不斷往可觀察對(duì)象數(shù)組中插入元素時(shí),可以設(shè)置一個(gè)周期時(shí)間1000ms,讓1000ms內(nèi)的所有操作集中到一次刷新中去,避免頻繁操作 DOM 帶來(lái)的性能惡化。

總結(jié)

本篇主要簡(jiǎn)單介紹了knockoutjs中最重要的概念:可觀察對(duì)象(數(shù)組)。可觀察對(duì)象實(shí)質(zhì)上是一個(gè)函數(shù)對(duì)象,通過(guò)ko方法操作可觀察對(duì)象時(shí)可以動(dòng)態(tài)刷新UI展現(xiàn),這個(gè)是推薦做法。同時(shí),也可以通過(guò)原生的js方法操作可觀察對(duì)象,只是原生方法并不會(huì)刷新UI展現(xiàn),需要等到下一次刷新事件時(shí)才會(huì)被刷新到UI中。

相關(guān)文章

  • JavaScript實(shí)現(xiàn)音樂(lè)播放器

    JavaScript實(shí)現(xiàn)音樂(lè)播放器

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)音樂(lè)播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 詳解瀏覽器渲染頁(yè)面過(guò)程

    詳解瀏覽器渲染頁(yè)面過(guò)程

    這篇文章主要介紹了詳解瀏覽器渲染頁(yè)面過(guò)程的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • JavaScript中日常收集常見(jiàn)的10種錯(cuò)誤(推薦)

    JavaScript中日常收集常見(jiàn)的10種錯(cuò)誤(推薦)

    本文是小編給大家日常收集整理的js中常見(jiàn)的10種錯(cuò)誤,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下
    2017-01-01
  • JavaScript數(shù)據(jù)綁定實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 MVVM 庫(kù)

    JavaScript數(shù)據(jù)綁定實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 MVVM 庫(kù)

    MVVM 是 Web 前端一種非常流行的開(kāi)發(fā)模式,利用 MVVM 可以使我們的代碼更專注于處理業(yè)務(wù)邏輯而不是去關(guān)心DOM 操作。接下來(lái)通過(guò)本文給大家介紹JavaScript使用數(shù)據(jù)綁定實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 MVVM 庫(kù),感興趣的朋友一起學(xué)習(xí)吧
    2016-04-04
  • JS?生態(tài)系統(tǒng)加速Polyfill函數(shù)使用實(shí)例探索

    JS?生態(tài)系統(tǒng)加速Polyfill函數(shù)使用實(shí)例探索

    這篇文章主要介紹了JS?生態(tài)系統(tǒng)加速Polyfill函數(shù)使用實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • JS冷知識(shí)之不起眼但有用的String.raw方法

    JS冷知識(shí)之不起眼但有用的String.raw方法

    String.raw是JavaScript中模板字符串的一個(gè)標(biāo)簽函數(shù),它的作用是將模板字符串不轉(zhuǎn)義的原始字符串內(nèi)容返回,接下來(lái)通過(guò)本文給大家介紹JS冷知識(shí)之不起眼但有用的String.raw方法,需要的朋友可以參考下
    2022-06-06
  • requirejs按需加載angularjs文件實(shí)例

    requirejs按需加載angularjs文件實(shí)例

    本篇文章主要介紹了requirejs按需加載angularjs文件實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • ES6 中可以提升幸福度的小功能

    ES6 中可以提升幸福度的小功能

    這篇文章主要介紹了ES6 中可以提升幸福度的小功能,在量解構(gòu)賦值的用途,函數(shù)的用處等方面給大家介紹,需要的朋友可以參考下
    2018-08-08
  • JavaScript算法題之如何將一個(gè)數(shù)組旋轉(zhuǎn)k步

    JavaScript算法題之如何將一個(gè)數(shù)組旋轉(zhuǎn)k步

    這篇文章主要給大家介紹了關(guān)于JavaScript算法題之如何將一個(gè)數(shù)組旋轉(zhuǎn)k步的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • JavaScript中forEach和map的使用場(chǎng)景

    JavaScript中forEach和map的使用場(chǎng)景

    本文JavaScript中forEach和map的使用場(chǎng)景,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05

最新評(píng)論