2016-12-29 83 views
1

我知道有get the new value of an observable in a subscribe event(在實際更改後)的解決方案,但我想知道是否可以在「beforeChange」訂閱中訪問observable的新值。在「beforeChange」訂閱中獲取可觀察值的新值

下面是current version of Knockout(3.4.1)與舊值分別新值提高beforeChange和改動後的訂閱處理程序的代碼段:

if (computedObservable.isDifferent(state.latestValue, newValue)) { 
    if (!state.isSleeping) { 
     computedObservable["notifySubscribers"](state.latestValue, "beforeChange"); 
    } 

    state.latestValue = newValue; 
    if (DEBUG) computedObservable._latestValue = newValue; 

    if (state.isSleeping) { 
     computedObservable.updateVersion(); 
    } else if (notifyChange) { 
     computedObservable["notifySubscribers"](state.latestValue); 
    } 

    changed = true; 
} 

顯然,NEWVALUE可在「beforeChange」等等我想分叉是一個選擇,但我不想。

是否有任何其他解決方案來獲得這個新值「beforeChange」?

+0

您能詳細說明爲什麼您要在設置之前獲取新值嗎? –

+0

@MichaelBest我試圖阻止FOUC。當我能夠在實際設置之前讀取新值時,我可以更新其他狀態以防止視圖的不必要的中間渲染 –

+0

您應該能夠使用計算或訂閱來更新第二個可用於觀察的值隱藏/顯示/樣式的東西。例如:https://jsfiddle.net/dmnqoc53/ – user3297291

回答

1

注更好:這個答案是基於對這個問題,而不是原來的問題你的評論。

當observable發生變化時,它會調用名爲notifySubscribers的observable方法,該方法執行實際通知,從而更新任何依賴於該observable的計算可觀察值,綁定等。如果你想在這些通知之前做某件事,你有幾個選擇。

  1. 正如@ user3297291所述,使用Ryan Niemeyer的protectedObservable

  2. 在任何其他訂閱它之前立即訂閱可觀察項。訂閱者總是按順序調用,所以你的代碼將永遠在別的之前運行。

  3. 覆蓋notifySubscribers掛鉤到通知過程中(記得調用上一個方法)。

  4. 可能淘汰賽3.5.0,會有a spectate eventchange事件之前發生。

1

編輯:我剛纔重讀你的問題,估計你可能是指你要檢查它設置之前新的價值?如果是這樣的話,你可能想要做一些像this


我通常創建兩個訂閱和一個額外的變量來跟蹤舊的(這你可能已經嘗試過):

var myObs = ko.observable(1); 
 

 
// Keep track of old 
 
var myObsOld = myObs(); 
 
myObs.subscribe(function(oldVal) { 
 
    myObsOld = oldVal; 
 
}, null, "beforeChange"); 
 

 
// Subscribe to new 
 
myObs.subscribe(function(newVal) { 
 
    console.log("myObs changed from", myObsOld, "to", newVal); 
 
}); 
 

 
myObs(2); 
 
myObs(3);
.as-console-wrapper { min-height: 100%; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

現在,如果你不不想用額外的變量和訂閱來拋棄你的視圖模型,你可以將這個邏輯封裝在擴展器中:

ko.extenders.latestValue = function(target, option) { 
 
    target.latestValue = target(); 
 
    
 
    target.subscribe(function(oldVal) { 
 
    target.latestValue = oldVal; 
 
    }, null, "beforeChange"); 
 
    
 
    return target; 
 
}; 
 

 
var myObs2 = ko.observable("a").extend({ latestValue: true }); 
 
myObs2.subscribe(function(newVal) { 
 
    console.log("myObs2 changed from", myObs2.latestValue, "to", newVal); 
 
}); 
 

 
myObs2("b"); 
 
myObs2("c");
.as-console-wrapper { min-height: 100%; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

不是一個非常性感的方式,但我認爲它比分叉回購:)

+0

感謝您的回答。事實上,我的問題是在真正改變之前檢索新的價值,而不是在改變之後檢索舊的價值。什麼會包裝可觀察的樣子?如何訂閱它? –