1

Let's say, I just have a common Knockoutjs layout/approach:

    function User(data) {
        this.name = ko.observable(data.name);
    }

    function UsersViewModel() {
        var self = this;

        self.users = ko.observableArray([]);
    }

    var viewModel = new UsersViewModel();
    service.initialize(viewModel);
    ko.applyBindings(viewModel);

and HTML:

<ul data-bind="foreach: users">
    <li>
        <span data-bind="text:name"></span>
    </li> 
</ul>

What I want is to apply some nice animation on the data changes in Knockoutjs: for existing DOM elements to disappear smoothly (which would take some time while the animation of disappearing finishes), and right after that (or even right on starting of disappearing) to start animation on new elements appearing. (In this very example -- for "li" elements to disappear separatly with every element separate animation (some delay between every element) (but that's not so important)).

(I consider here just will be a full replacement of elements (let's say not to be bothered much if new data contains items with the same id... that's complicated, I understand that)).

As I understand, that might be pretty tough, and I should consider to change/extend Knockoutjs sources (right?) to deal with "start-disappearing-animation", "disappearing-animation-finished", "start-appearing-animation".

But is there at least any way to prevent knockout to delete existent DOM elements (for me to handle that manually)... some way to "detach" them from container.

Or, if nothing else above possible, then just to have "on before data changing" event?

Thank you!

Agat
  • 4,577
  • 2
  • 34
  • 62
  • 1
    Check out the docs on [custom bindings](http://knockoutjs.com/documentation/custom-bindings.html) they have an example of an animated transition and you could probably extend that to whatever you need. – Matt Burland Jan 31 '14 at 19:57
  • Hm... but that seems that "update" callback is rather for refreshing some element's state (in case, if in my example some `name` of some `user` data-object would change), but not allowing actually to call the animation after (and especially, before) some new elements appear/disappear (i.e., DOM object removed/created). – Agat Jan 31 '14 at 20:32
  • Either way, what you are looking for is a custom binding handler. – PW Kad Jan 31 '14 at 20:41
  • Could you be more specific? As I've just mentioned above, I can not see how is that possible to have something like 'on disposing/on removing' (in opposite to 'update' from the custom binding). – Agat Jan 31 '14 at 20:43

1 Answers1

0

You can use a custom binding to update the element.

You will then be able to do what you want before and after updating the element yourself.

Generic example:

ko.bindingHandlers.textAnimated = {
    update: function(element, valueAccessor) {
        var value = valueAccessor();

        var valueUnwrapped = ko.utils.unwrapObservable(value);

        // Before changing value
        // Do something

        $(element).text(valueUnwrapped);        

        // After changing value
        // Do something else
    } 
};

Example for a custom binding fading out the old value, then fading in the new value then printing done on the console:

ko.bindingHandlers.textAnimated = {
    update: function(element, valueAccessor) {
        var value = valueAccessor();

        var valueUnwrapped = ko.utils.unwrapObservable(value);

        $(element).fadeOut('slow', function() {
            $(element).text(valueUnwrapped);       

            $(element).fadeIn('slow', function() {
                console.log('done');
            });
        });
    } 
};

See the JSFiddle

leszek.hanusz
  • 5,152
  • 2
  • 38
  • 56
  • Thanks for the answer, I am looking for another thing though. I need something rather not for the `title` to change (and indicate), but for the container `
      `. However, I can try something like this for it as well.
    – Agat Jan 31 '14 at 20:54
  • Check this: http://stackoverflow.com/questions/18955314/knockoutjs-foreach-custom-bindinghandler-with-afteradd – leszek.hanusz Jan 31 '14 at 21:08