Knockout相依性追蹤實驗
0 |
之前有個錯誤認知,想像Knockout會在ko.computed宣告時期分析其與哪些obersvable相依,藉此訂閱變更事件,實現相依observable變動後立即重算的能力。在範例20時踢到鐵板! 情境是ko.computed因if條件式在某些情況下不會讀取observable,沒想到此後該obersvable的變動便不再觸發重算。這才驚覺,原來的想法錯得離譜!!
JavaScript是直譯式語言,未經事先編譯,一定要實際執行過才知函數邏輯,怎麼會出現"宣告時期如何如何"的情境? (謎之聲: 連這都錯,出來打手心) 更進一步,由觀察結果發現: 每次執行computed後,Knockout會重新定義其相依關係,這次沒讀取到的observable,就失去了相依關係,下回該observable變動時將不再觸發重算。
我們設計一個實驗來驗證這個行為:
<!DOCTYPE html>
<html>
<head>
<title>相依追蹤實驗</title>
<script src="../Scripts/jquery-1.7.2.js"></script>
<script src="../Scripts/knockout-2.1.0.debug.js"></script>
<script>
$.ajaxSettings.cache = false;
function MyViewModel() {
var self = this;
self.text1 = ko.observable("Jeffrey");
self.text2 = ko.observable("Darkthread");
self.textPlus = ko.observable();
self.textSharp = ko.observable();
self.recalcTime = ko.observable(new Date().getTime());
ko.computed(function () {
self.recalcTime(new Date().getTime());
self.textPlus(self.text1() + "+");
if (self.text1() != "Disable") {
self.textSharp(self.text2() + "#");
}
});
}
$(function () {
ko.applyBindings(new MyViewModel());
});
</script>
<style>
body, input
{
font-size: 9pt;
}
.disp
{
background-color: #C0C0C0;
}
</style>
</head>
<body>
<input type="text" data-bind="value: text1" style="width: 80px;"/>
<input type="text" data-bind="value: textPlus" class="disp" readonly /><br />
<input type="text" data-bind="value: text2" style="width: 80px;"/>
<input type="text" data-bind="value: textSharp" class="disp" readonly /><br />
<span data-bind="text: recalcTime"></span>
<br />
</body>
</html>
網頁上有兩個可輸入的<input>,分別繫結到text1及text2兩個observable,其後分別跟著兩個唯讀<input>,分別繫結到textPlus及textSharp兩個observable。定義了一個computed,將text1加上"+"號寫入textPlus,將text2加上"#"號寫入textSharp,但有個特別條款,若text1() == "Disable",便不更新textSharp。為了明確掌握重算發生時機,再定義一個recalcTime屬性,每次computed執行時填入new Date().getTime(),由數字變化藉以確認computed是否被呼叫執行。
一開始,不論修改text1或text2,textPlus及textSharp都會立即連動。接著我們在text1填入"Disable",便可發現之後再修改text2,textSharp都不會變更,但這有可能是if (text1() == "Disable")不成立造成的,所以我們需要由下方的數字判定: 當text1=="Disable"時,修改text2便不會引發下方數字改變,證明了KO已不再判定computed與text2相依!
接著,我們將text1改回非"Disable",textSharp馬上更新,之後修改text2也會觸發下方數字跳動,驗證KO已再次認定computed與text2相依。
由此實驗得知,KO會在每次computed執行後重新定義相依關係! 在設計一些進階computed應用時,可留意此原則。
Comments
Be the first to post a comment