【茶包射手日記】KO 3.3升級不相容之偵錯練習

專案由Knockout.js  3.2升級到3.3後,某個網頁原本使用<!-- ko if … -->切換元素顯示的功能失效,抓了一陣子才發現原來是寫法有誤,原本該寫<!-- ko if: someFalg -->卻寫成<!-- ko if (someFlag) -->,修改為<!-- ko if: someFlag -->問題即告排除。

但這激起我的好奇心,想找出3.2到3.3造成此一行為差異的根源改變。(其實是手癢想練習JavaScript偵錯技巧)

用一段小程式重現問題:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>if/ifnot Test</title>
</head>
<body>
  <input type="checkbox" data-bind="checked: Flag" />
  Flag = <span data-bind="text: Flag"></span>
  <div>
  <!-- ko if (Flag) -->
  Flag On
  <!-- /ko -->
  <!-- ko ifnot (Flag) -->
  Flag Off
  <!-- /ko -->
  </div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
  <script>
  ko.applyBindings({ Flag: ko.observable(true) });
</script>
</body>
</html>

測試結果,使用KO 3.2可以順利切換Flag On及Flag Off,使用KO 3.3則if/ifnot失效,Flag On及Flag Off永遠出現。

開啟F12偵錯,設定中斷點,一步一步挖進去,終於找出差異禍首:

KO 3.3調整了內部函式parseObjectLiteral()的邏輯,這個函式負責分析縏結字串轉為Key/Value配對,以找出對應的繫結處理器,例如:"text: Prop"會轉成Key="text",Value="Prop",代表要使用text繫結,繫結對象是Prop。

設定程式中斷點,直接呼叫parseObjectLiteral()進行測試。程式誤寫的非典型繫結字串"if(Flag)"(正確應為"if:Flag"),使用KO 3.2的parseObjectLiteral()還是可以正確解析出Key="if", Value="Flag"。

到了KO 3.3,因parseObjectLiteral()內部有個if條件修改,"if(Flag)"已不再視為有效,會被歸為unknown。至於if:Flag在KO 3.2跟3.3都可正確解析。

成功鎖定目標,偵錯練習完畢。

歡迎推文分享:
Published 14 May 2015 07:52 AM 由 Jeffrey
Views: 4,042



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<May 2015>
SunMonTueWedThuFriSat
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication