knockoutjs-邊入門邊填坑(2)

這里是古老mvvm框架knockoutjs的學(xué)習(xí)總結(jié),邊入門邊填坑(2)

在上一篇總結(jié)中,描述了一個CRUD簡單例子霎奢,實現(xiàn)當(dāng)前頁面內(nèi)的所有操作均為異步刷新益愈,有很好的用戶體驗梢灭。同時開發(fā)人員編程也有固定的模式,弱化了jquery的直接DOM操作(僅用于ajax請求提交)蒸其,強(qiáng)化了ko的數(shù)據(jù)操作(所有數(shù)據(jù)操作敏释,事件操作)。如果有合適的異步請求插件摸袁,jquery也是可以放棄的钥顽。事實上單頁angular和vue框架已經(jīng)看不到j(luò)query了。

以下是代碼中的一些細(xì)節(jié)分析:
1.click事件

//當(dāng)前使用的click事件寫法
data-bind="click:function(){return $root.editUser(vo)},clickBubble:false"
//可以優(yōu)化為
data-bind="click:$root.editUser,clickBubble:false"

click事件的優(yōu)化寫法

點擊事件的模式化寫法(循環(huán)內(nèi))
1.<span class="attent" data-bind="click:$root.followOne,clickBubble:false">+&ensp;關(guān)注</span>
2.<span class="attent" data-bind="click:$root.followOne2.bind($data,'里','中'),clickBubble:false">+&ensp;關(guān)注2</span>
    viewModel.followOne = function(item,event){//1.獲取本行靠汁,event
        console.log(ko.toJS(item))  //vo
        console.log(event.shiftKey)  //event
    }
    viewModel.followOne2 = function(d1,d2,item,event){//2.獲取本行蜂大,event闽铐,以及d1,d2
        console.log(d1)// 里
        console.log(d2)// 中
        console.log(ko.toJS(item)) //vo
        console.log(event.shiftKey) //event
    }       

點擊事件的模式化寫法(循環(huán)外)
3.<a href="#" data-bind="click:$root.testClick1,clickBubble:false">測試點1</a>
4.<a href="#" data-bind="click:$root.testClick2.bind($data,'里','中'),clickBubble:false">測試點2</a>
viewModel.testClick1 = function(dto,event){//3.獲取dto,event
        console.log(dto.limit()) //dto
        console.log(event.shiftKey) //event
    }
    viewModel.testClick2 = function(d1,d2,dto,event){//4.獲取dto,event,以及d1,d2
        console.log(d1) //里
        console.log(d2) //中
        console.log(dto.limit()) //dto
        console.log(event.shiftKey) //event
    }

2.回車觸發(fā)事件
用戶新增了記錄1,在輸入框填寫數(shù)據(jù)后奶浦,可以直接回車兄墅,觸發(fā)新增用戶。

//頁面上給input綁定了ko的事件監(jiān)聽
//keypress:$root.searchKeyboardCmd采用了事件的模式化寫法(循環(huán)內(nèi))
data-bind="value:vo.username,valueUpdate:'keyup',event:{keypress:$root.searchKeyboardCmd}"

//回車觸發(fā)確認(rèn)新增用戶
    viewModel.searchKeyboardCmd = function (data, event) { 
        if(event.keyCode == 13){
            viewModel.saveOneItem(data)
            return false;
        }
        return true;
    }

3.mapping的使用
新增userItem到ko的resultList列表中澳叉,此時userItem的ID是空的瓷患。提交新增請求辣苏,成功后绳军,需要用后臺返回的json對象obj.data賦值給ko的vo

//使用mapping把后臺的json數(shù)據(jù)賦值給ko對象
 ko.mapping.fromJS(obj.data,{},vo);

使用mapping需要了解js對象彰导,json對象和ko對象的區(qū)別,它們之間是可以互相轉(zhuǎn)換的
json : 來自后臺瓶殃,通常由后臺服務(wù)返回JSON對象充包,包含列表,單個對象等 {status : 0 , message:'各種提示',data:{實際數(shù)據(jù)包}} (json對象)
js:從json獲得實際數(shù)據(jù)包 xx.data (js對象)
ko: 把js對象用ko.mapping.fromJS轉(zhuǎn)化成vo (ko對象)

json         ---->                  js        ----->                    ko      ------->                js          ---->       json
            ko.utils.parseJson        ko.mapping.fromJS(xxDTO,{} viewModel)      ko.mapping.toJS/ko.toJS        JSON.stringify
            JSON.parse

4.valueHasMutated
往列表中插入新KO對象碌燕,會觸發(fā)列表上其他對象的KO事件误证,如果一次加多個,有時會觸發(fā)多次修壕,為了避免這個問題愈捅,加入了valueHasMutated方法,讓所有新對象全部加入后慈鸠,才執(zhí)行一次觸發(fā)事件蓝谨。

其他的ko用法還有自定義綁定ko.bindingHandlers,全選/反選青团,列表渲染后自定義觸發(fā)等譬巫。

5.my97DatePicker在ko中正確的顯示時間

//頁面使用新的日期綁定
data-bind="my97DatePicker:criteriaVO.headTime,sdf:'yyyy-MM-dd'"

//自定義 my97DatePicker
ko.bindingHandlers.my97DatePicker = {
            init: function (element, valueAccessor,allBindings) {
                var sdf = allBindings.get('sdf') || 'yyyy-MM-dd HH:mm:ss';  
                $(element).click(function() {
                    WdatePicker({dateFmt: sdf,onpicking:function(dp){
                            var nt = dp.cal.getNewDateStr()
                            valueAccessor()(nt)
                        },
                        oncleared:function(dp){
                            var nt = dp.cal.getNewDateStr()
                            valueAccessor()('')
                        }
                    })
                });
            },
            update: function (element, valueAccessor) {
                var v = valueAccessor()();
                $(element).val(valueAccessor()());
                if(v != null && v != ''){
                }
            }
    };

6 全選/反選
以前寫checkbox的全選,反選督笆,用jquery很繁瑣芦昔,因為是直接操作DOM視圖。ko的思想則不同娃肿,開發(fā)者只操作ko數(shù)據(jù)咕缎,具體視圖交給ko自行渲染

//頁面-全選
data-bind="checked:selectAll"
//頁面-每一行
<input type="checkbox" data-bind="checked:fvo.fileCheck" >

//JS
viewModel.selectAll = ko.computed({
        //全選hkj
        read : function() {
            var item = ko.utils.arrayFirst(viewModel.yunFileVOs(), function(item) {
                return !item.fileCheck();
            });
            return item == null;           
        },
        write : function(value) {
            ko.utils.arrayForEach(viewModel.yunFileVOs(), function (item) {
                item.fileCheck(value);
            });
            
        }
    });
  1. pushAll
    ko沒有類似pushAll的語法。料扰。凭豪。所以要批量提交,需要自實現(xiàn)晒杈。
//頁面
viewModel.teacherRecommends.pushAll(valuesToPush)
//自實現(xiàn)pushAll嫂伞,接收J(rèn)S數(shù)組為參數(shù)
ko.observableArray.fn.pushAll = function(valuesToPush) {
       for(var i = 0 ; i < valuesToPush.length ; i++ ){
           var tempV = valuesToPush[i]
           console.log(">>>PUSH ALL :"+tempV.teacherId+"-"+tempV.realName)
           console.log(tempV.teacherId != '')
           if(tempV.teacherId != ''){
               this.push(ko.mapping.fromJS(tempV))
               
           }
       }
       this.valueHasMutated();//再次使用了valueHasMutated
       return this;
    };

KO的坑還是有的,但都有適配的方法來解決,而且都很容易做到√現(xiàn)在我主要把KO當(dāng)一個簡單的mvvm庫來使用撰豺,這是它的天然優(yōu)勢,值得好好學(xué)習(xí)拼余。再深入學(xué)習(xí)的話郑趁,就是組件了。如果做單頁項目姿搜,建議轉(zhuǎn)VUE學(xué)習(xí)

KO+路由也是可以做的,看這里
durandal框架(內(nèi)置路由捆憎,搭配ko,requirejs)
http://durandaljs.com/get-started.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舅柜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子躲惰,更是在濱河造成了極大的恐慌致份,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件础拨,死亡現(xiàn)場離奇詭異氮块,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诡宗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門滔蝉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人塔沃,你說我怎么就攤上這事蝠引。” “怎么了蛀柴?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵螃概,是天一觀的道長。 經(jīng)常有香客問我鸽疾,道長吊洼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任制肮,我火速辦了婚禮冒窍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘弄企。我一直安慰自己超燃,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布拘领。 她就那樣靜靜地躺著意乓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上届良,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天笆凌,我揣著相機(jī)與錄音,去河邊找鬼士葫。 笑死乞而,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的慢显。 我是一名探鬼主播爪模,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼荚藻!你這毒婦竟也來了屋灌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤应狱,失蹤者是張志新(化名)和其女友劉穎共郭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疾呻,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡除嘹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了岸蜗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尉咕。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖散吵,靈堂內(nèi)的尸體忽然破棺而出龙考,到底是詐尸還是另有隱情矾睦,我是刑警寧澤晦款,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布枚冗,位于F島的核電站,受9級特大地震影響赁温,放射性物質(zhì)發(fā)生泄漏坛怪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一股囊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧稚疹,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至岩灭,卻和暖如春拌倍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柱恤。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工找爱, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留膨更,地道東北人缴允。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓珍德,卻偏偏與公主長得像练般,于是被迫代替她去往敵國和親锈候。 傳聞我的和親對象是個殘疾皇子薄料,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容