Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should be able to unapply bindings #724

Closed
mberkom opened this issue Nov 20, 2012 · 12 comments
Closed

Should be able to unapply bindings #724

mberkom opened this issue Nov 20, 2012 · 12 comments

Comments

@mberkom
Copy link

mberkom commented Nov 20, 2012

Knockout should have a complete method for unapplying bindings. I've written my own that seems to work fairly well and would like to see something similar integrated into the core.

// accepts jQuery node and remove boolean
ko.unapplyBindings = function ($node, remove) {
    // unbind events
    $node.find("*").each(function () {
        $(this).unbind();
    });

    // Remove KO subscriptions and references
    if (remove) {
        ko.removeNode($node[0]);
    } else {
        ko.cleanNode($node[0]);
    }
};

This is especially useful when setting up a Knockout viewmodel as a widget which can be added and removed dynamically.

@mbest
Copy link
Member

mbest commented Nov 20, 2012

Your example will not work if the "widget" contains control-flow bindings. It will "unbind" okay, but the resulting html may not be the same as the original. Knockout already has the with and template bindings to handle this sort of situation.

@mberkom
Copy link
Author

mberkom commented Nov 20, 2012

with and template are both really useful bindings, but they fall short in certain situations. Specifically, they require directly coupled viewmodels and views. I'm looking for a pattern where models can be passed between two or more viewmodels and the viewmodels remain completely decoupled from each other. See aura for an example of what I'm getting at.

I've never tried to "rebind" the html after "unbinding" because I always remove the html.

@mberkom
Copy link
Author

mberkom commented Nov 21, 2012

I've mocked up a quick example of how I'm using the method in combination with Ryan Niemeyer's ClassBindingProvider here: http://jsfiddle.net/mberkom/genXq/13/

@SteveSanderson
Copy link
Contributor

Creating a way of removing bindings would be quite a significant change - it would mean that all existing bindings (including custom bindings) would need some extra callback function (e.g., dispose) to tell them to undo or release whatever non-GCable stuff they've created (e.g., event handlers, DOM data, etc.). Calling cleanNode alone isn't enough because the custom binding might have made additional changes elsewhere or applied delegated events elsewhere.

All that said, I can appreciate it would permit extra flexibility in some cases. I'll keep this issue report open as a possible future enhancement.

I've mocked up a quick example

Sorry, I didn't really follow what you were doing here or how it differs from usual patterns. Could you clarify?

@mberkom
Copy link
Author

mberkom commented Nov 30, 2012

Sorry, I didn't really follow what you were doing here or how it differs from usual patterns. Could you clarify?

Yes, I can. Following the concept of large scale JS application architecture found here, I created an object I call the Knockout Module. It's a viewmodel wrapped with start and stop methods designed to insert the viewmodel, instantiate, and then remove it. My fiddle is an example of how it operates. I'm using the Class Binding Provider to keep the HTML clean and allow for better debugging.

By declaring a viewmodel with my Knockout Module pattern, it is now possible to insert an editing interface anywhere without requiring it to be nested beneath another viewmodel's bindings. See my question here for a possible application. I'm currently using it for loading a form to edit table rows.

@rmeschian
Copy link

Hi Steve,

First, thanks for an awesome library. We definitely need an uninit callback in bindings. I'm building a rich application where widgets are often created and destroyed (each widget is like a page, with ko bound data), so I need a way to clean up to avoid mem leaks.

Thanks!

@vicary
Copy link

vicary commented Dec 9, 2012

+1 For a solution of mem leaks. Doesn't have to be a complicated unbind, or even reverting back to the state before binding. Just need a way to dispose things no longer needed.

@jelling
Copy link

jelling commented Sep 4, 2013

+1 for this. I have situation where we have to pre-render the DOM elements to prevent locking up IE7/8. mberkom's function is a big help.

@jelling
Copy link

jelling commented Sep 9, 2013

FYI, Mberkom's unapplybindings script is also excellent at reducing IE7 memory leaks. I added it to my page.unload and it helped a good bit.

@dnutels
Copy link

dnutels commented Dec 25, 2013

My concern for this mostly lies with clashes between KO and other frameworks - namely Backbone or jQuery. Having cleanNode remove all the bindings, including those that do not belong to KO creates a multitude of problems.

Simply put - using jQuery's on(event, root, function(){ ... }) to delegate events to the root and then applyBindings to that same root is doomed if there is a need to re-apply bindings as it would make calling cleanNode not feasible.

@jrsearles
Copy link

This appears to be very similar to issue #41.

@rniemeyer
Copy link
Member

Closing. Conversation can continue in #41.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants