2012-07-19 8 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>

EDIT: Другой возможно проще вариант Я придумал только теперь использовать расширение дроссельной заслонки на переменной, которую вы используете with с:

ViewModel:

///...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 начнет переход элемента. Тогда в тот момент, когда он будет исчезать (200 мс в этом случае), дроссель догонит, и delayedObservable будет обновляться правильно, так как fadeInOut начинает исчезать элемент назад. Он исчезает и исчезает в другом.

+1

Я попробовал первое решение, прежде , но кажется, что в 'с' функция обновления привязки не вызывается. –

+0

Я более уверен в том, что 3-е решение действительно работает, чем первое, так как я не вижу никакого способа «отпустить» страницу для рендеринга, сохраняя при этом функцию обновления в первом решении, чтобы он мог вернуть значение функции обновления (это то, что происходит ... значение возврата с обновлением теряется и фактически важно, потому что оно управляет децидентными элементами). –

0

Решение Los Frijoles 3rd не будет работать, поскольку оно будет дросселировать привязку «с», которая всегда будет иметь место после анимации.

Поскольку мы пытаемся анимировать элементы, создаваемые привязкой привязки, при переходе из состояния без передачи в отображаемое состояние анимация будет пытаться анимировать элементы, которые не существуют.

Ответ Slawomir - это лучшее, что я видел, но клонирование сложных элементов при анимации на мобильных устройствах не является вариантом для повышения производительности. Для правильной реализации анимаций для этих привязок требуется усовершенствование структуры нокаута.

Редактировать: Я понял, что можно оживить привязку «с» или «если», заменив ее тегом «шаблон» или «foreach» эквивалентной логики.Например, я заменил:

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

с:

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

Там нет необходимости 'selectedTimelapse' из моего примера, чтобы быть списком. Используя это, я могу теперь входить и выходить из модального диалога, когда выбраноTimelapse. Этот метод может быть взломан работать, если переходы, а также:

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

Мои utils.kbAnimFadeIn/Out функции эквивалентны функциям продемонстрированных в анимации пример страницы Knockout здесь: http://knockoutjs.com/examples/animatedTransitions.html

Смежные вопросы