Knockout中ViewModel与Model的互转
??? 在我們平常的開發(fā)當(dāng)中使用頻率最多的就是CRUD(添加、更新、刪除、查詢)。 而“添加”和“編輯”操作又是整個(gè)數(shù)據(jù)源的入口,在整個(gè)CRUD中占有非常重要的地位。常規(guī)情況下我們做一個(gè)編輯操作時(shí),首先需要將實(shí)體對(duì)象從數(shù)據(jù)庫(kù)中提取出來并將其值展示在頁面上供用戶進(jìn)行編輯。用戶編輯完成之后點(diǎn)擊提交按鈕時(shí)我們需要再將實(shí)體對(duì)象的值從頁面中提取出來,并組成一個(gè)完整的實(shí)體對(duì)象提后交到后臺(tái)進(jìn)行處理。
??? 那么這種業(yè)務(wù)場(chǎng)景我們?nèi)绾蝸硎褂胟nockout來完成呢?ko是一種MVVM(Model-View-ViewModel)模式的應(yīng)用,本質(zhì)上我們的實(shí)體對(duì)象是一個(gè)數(shù)據(jù)模型也就是model,如果我們想要它展示在View上邊那么就需要將它轉(zhuǎn)化為ViewModel。同理,如果我們想要取得頁面的數(shù)據(jù)信息,那么也就需要再將ViewModel轉(zhuǎn)換為model。這樣我們需要解決的兩個(gè)是:
??? 1、展示數(shù)據(jù)時(shí)我們需要將model轉(zhuǎn)換為ViewModel 。
??? 2、提交數(shù)據(jù)之前,我們需要將ViewModel轉(zhuǎn)換為model對(duì)象
Model轉(zhuǎn)換為ViewModel
??? ko的監(jiān)控機(jī)制是一個(gè)典型的“觀查者”模式的實(shí)現(xiàn)。ko.observable()方法將對(duì)象轉(zhuǎn)換為一個(gè)監(jiān)控對(duì)象,即:“被觀察者”,通過使用“被觀察者”的subscribe方法來注冊(cè)“觀查者”。首先,我們定義一個(gè)實(shí)體對(duì)象(entity)并將它監(jiān)控起來,然后我們訂閱一個(gè)專門的用來將Model轉(zhuǎn)換為ViewModel的Listener。當(dāng)這個(gè)Listener接收到entity發(fā)生變化的通知時(shí),將對(duì)entity的屬性進(jìn)行檢測(cè),如果它沒有被監(jiān)控,則將它轉(zhuǎn)換為一個(gè)監(jiān)控對(duì)象。ko.isObservable是ko官方提供的一個(gè)輔助API,它返回一個(gè)Boolean值,用來判斷對(duì)象是否已經(jīng)被ko監(jiān)控。
//案例視圖模型 function viewModel() {var model = this;//使用ko.observable將實(shí)體對(duì)象監(jiān)控起來this.entity = ko.observable()//注冊(cè)一個(gè)用來將entity轉(zhuǎn)換為viewModel的listenerthis.entity.subscribe(function (newValue) {//判斷屬性children是否已經(jīng)被監(jiān)控if (newValue && !ko.isObservable(newValue.children)) {//將children屬性轉(zhuǎn)為監(jiān)控對(duì)象newValue.children = ko.observableArray(newValue.children || []);//將name屬性轉(zhuǎn)換為監(jiān)控對(duì)象newValue.name = ko.observable(newValue.name);}}); }ViewModel轉(zhuǎn)換為Model
??? 將ViewModel轉(zhuǎn)換為Model是一個(gè)讓很多新手很痛苦的地方。常規(guī)情況下因?yàn)閑ntity的屬性因在轉(zhuǎn)換為ViewModel時(shí)被轉(zhuǎn)換為“被觀察者”也就是由屬性變成了一個(gè)函數(shù),我們需要它再次將它轉(zhuǎn)回為屬性。并且因?yàn)閂iewModel和頁面顯示是直接相關(guān)聯(lián)的,我們這時(shí)候還不能直接修改entity對(duì)象,因?yàn)橐坏┌l(fā)生修改,那么頁面也跟隨著發(fā)生變化。所以實(shí)際上我們需要clone一個(gè)entity對(duì)象,并將監(jiān)控對(duì)象轉(zhuǎn)換為屬性。這個(gè)過程相對(duì)來講比較麻煩,也是很多人抱怨的地方。
??? 實(shí)質(zhì)上knockout已經(jīng)幫我們想到并處理了這個(gè)問題。ko.toJS方法就是官方提供的一個(gè)專門用來轉(zhuǎn)換ViewModel的輔助API,它可以自動(dòng)將監(jiān)控對(duì)象轉(zhuǎn)為屬性對(duì)象。同時(shí)ko還提供了一個(gè)ko.toJSON方法,它會(huì)將ViewModel直接轉(zhuǎn)換為model的json字符串形式。那么我們定義一個(gè)json對(duì)象,它的值就是viewModel轉(zhuǎn)為json字符串展示在頁面上,讓我們可以即時(shí)的看到頁面發(fā)生變化時(shí)實(shí)體對(duì)象同時(shí)跟隨發(fā)生的變化。
//實(shí)體對(duì)象生成的字符串,并來在頁面上同步展示View發(fā)生的變化 this.json = ko.computed(function () {return ko.toJSON(model.entity); });頁面ViewModel
<div id="case" data-bind="with:entity" style="padding-left:25px;"><div><label>名稱:</label> <input data-bind="value: name" /> </div><div><label>子級(jí):</label><ul style="display:inline-block"><!-- ko foreach:children --><li data-bind="text:$data"></li><!-- /ko --><li><input data-bind="value:$root.newChildName" /><input data-bind="click:$root.addChildEventHandle" type="button" value="增加" /></li></ul></div><div style="margin-top:50px;"><label>json:</label><label data-bind="text:$root.json"></label></div> </div>綁定頁面視圖
var model = new viewModel();model.entity({name: '張三',children: ['狗子','二蛋'] });ko.applyBindings(model, document.getElementById('case'));完整示例代碼
下載
轉(zhuǎn)載于:https://www.cnblogs.com/lswweb/p/3673966.html
總結(jié)
以上是生活随笔為你收集整理的Knockout中ViewModel与Model的互转的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C文件操作之写入字符串到指定文件并在屏幕
- 下一篇: 文件压缩与解压