2012-07-19 45 views

回答

1

我通過創建創建元素副本的綁定來解決問題。在克隆這個元素之後,我對它進行動畫處理,然後刪除它並用新值賦予原始元素動畫效果。在之前設置此綁定很重要

3

你總是可以用你自己的綁定,以便用jQuery進行一些動畫,像這樣結合包裹:

ko.bindingHandlers['fadingWith'] = { 
    init: function(element, valueAccessor, allBindingsAccessor, context) { 
     return ko.bindingHandlers['with']['init'](element, valueAccessor, allBindingsAccessor, context); 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, context) { 
     $(element).fadeOut(100, function() { 
      ko.bindingHandlers['with']['update'](element, valueAccessor, allBindingsAccessor, context) 
     }).fadeIn(100); 
    } 
}; 
ko.virtualElements.allowedBindings['fadingWith'] = true; 

那麼你可以申請它像這樣:<div data-bind="fadingWith: someObservable"><span data-bind="text: $data"></span></div>

我沒有測試過這(我會在稍後嘗試),但我認爲這將是方向。

另一種選擇(這我更加肯定會工作)是您創建一個單獨的綁定,執行以下操作:

ko.bindingHandlers['fadeOn'] = { 
    update: function(element) { 
     $(element).hide().fadeIn(200); 
    } 
} 

這不會給你的動畫之前觀察到的變化,但它之後會給你一個動畫。所以,你會做<div data-bind="with: someObservable, fadeOn: someObservable"><span data-bind="text: $data"></span></div>

編輯:另一個可能更容易我剛纔想出了選擇是使用您所使用with與可變節氣門擴展:

視圖模型:

///...your code.... 
this.observableThatNeedsWith = ko.observable("Hello"); 
this.delayedObservable = ko.computed(this.observableThatNeedsWith).extend({throttle: 200}); 
//...continue your code 

然後,你有一個綁定,如下所示:

ko.bindingHandlers['fadeInOut'] = { 
    update: function(element) { 
     $(element).stop(true, true).stop(true, true).fadeOut(200).fadeIn(200); 
    } 
} 

請注意,淡出時間與節流時間相同。

然後你把它綁定像這樣:<div data-bind="with: delayedObservable, fadeInOut: observableThatNeedsWith"><span data-bind="text: $data"></span></div>

會發生什麼事是,當你改變observableThatNeedsWith,該fadeInOut處理程序將開始轉換的元素。然後當它完成淡出(在這種情況下爲200ms)時,油門會跟上並且delayedObservable將會正確更新,因爲fadeInOut會開始淡化這個元素。它會淡化一個東西,然後淡入另一個。

+1

我嘗試過第一個解決方案,但似乎在'與'綁定更新函數不會被調用。 – 2012-07-19 17:48:03

+0

我對第三個解決方案比第一個解決方案更有信心,因爲我沒有看到任何方法來「釋放」頁面來進行渲染,同時仍然保持第一個解決方案中的更新功能處於活動狀態,以便它可以返回值的更新函數(這就是發生了什麼...與更新返回值正在失去,其實際重要,因爲它控制deceiva元素)。 – 2012-07-19 20:48:21

0

Los Frijoles 3rd解決方案將不起作用,因爲它會限制'with'綁定始終發生在動畫之後。

由於我們試圖使用綁定呈現的元素進行動畫處理,因此當從未呈現狀態轉換爲呈現狀態時,動畫將嘗試對不存在的元素進行動畫處理。

Slawomir的答案是我見過的最好的答案,但是在移動設備上進行動畫製作時,克隆複雜元素不是性能方面的選擇。正確地爲這些綁定實現動畫需要改進Knockout框架。

編輯: 我意識到可以通過用'template'或'foreach'等效邏輯標籤替換'with'或'if'綁定來設置動畫效果。舉例來說,我代替:

<div data-bind="with: selectedTimelapse"> 

有:

<div data-bind="template: { 
    foreach: selectedTimelapse, 
    afterAdd: utils.kbAnimFadeIn, 
    beforeRemove: utils.kbAnimFadeOut 
}"> 

沒有必要從我的例子 'selectedTimelapse' 是一個列表。使用這個我現在可以在設置selectedTimelapse時進入和退出我的模態對話框。這種技術可以對黑客攻擊的,如果轉換以及工作:

<div data-bind="template: { 
    foreach: (showTimelapse()) ? selectedTimelapse : undefined, 
    afterAdd: utils.kbAnimFadeIn, 
    beforeRemove: utils.kbAnimFadeOut 
}"> 

我utils.kbAnimFadeIn輸入/輸出功能,相當於在淘汰賽動畫示例頁面這裏展示的功能:http://knockoutjs.com/examples/animatedTransitions.html