简体   繁体   中英

Changing observable array alters visibility of custom binding handler, knockoutjs

Update: JSFiddle http://jsfiddle.net/OrganicCat/CjH87/6/

I have an area that is populated by a normal observable array, and when a button is clicked, an asynchronous service call is made that repopulates that array, but with more data.

This also causes a hidden dom element to display and displays some of that array data there.

Everything works fine until the observable array data is updated, it closes the hidden dom element. It is this event inside Knockout.js(library) that triggers it:

// Ignore writes if the value hasn't changed
    if ((!observable['equalityComparer']) || !observable['equalityComparer'](_latestValue, arguments[0])) {
    observable.valueWillMutate();
    _latestValue = arguments[0];
    if (DEBUG) observable._latestValue = _latestValue;
    observable.valueHasMutated(); // This event HERE

Is there a way to prevent this from closing the custom binding? Could anything in the binding be causing this? Here is my custom binding handler:

ko.bindingHandlers.expandAmenities = {
                init: function (element) {
                    $('.expandable.closed').hide();
                    $('.itineraryRowMain .t-go .toggle-expand-rowAmenities').unbind('click').on('click', function (e) {

                        var $itin_body = $(this).closest('.module-admin-group');
                        if ($itin_body.hasClass('closed')) {
                            $(this).parent().parent().next().show();
                            self.bindAmenities(); // Bind amenity details on open
                            //$(this).children().html('-');
                        } else {
                            $(this).parent().parent().next().hide();
                            //$(this).children().html('+');
                        }
                        $itin_body.toggleClass('open closed');
                    });
                }
            };

To summarize, the expand area has a clickable element that will show more data. When this updates the array (just a plain old self.listofStuff(arr);) this causes the new area to get hidden again.

I've figured out the answer. So the problem is that if you bind an array that generates DOM elements (like a list or whatever) and you have elements inside that array that you want to update without doing a .push and without resetting the entire array with self.myArray(newArray) then you have to use an observable variable within the array and update that.

When you modify the observable, it will not redraw the entire array, thereby keeping your dynamically altered elements (like visible/hidden divs within the DOM array) in the same state if they were altered by jQuery or whatever.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM