Knockoutjs foreach custom bindinghandler with afterAdd

前端 未结 2 1401
遇见更好的自我
遇见更好的自我 2021-02-10 21:22

I would like to build a custom bindingHandler

ko.bindingHandlers.foreachWithHighlight that has an highlight effect when afterAdd.

From documentation

<         


        
相关标签:
2条回答
  • 2021-02-10 21:47

    I've modified one of the knockout tutorials, it doesn't use a custom binding though but still drives the behaviour via beforeRemove and afterAdd which hook into the observableArray.

    data-bind='template: { 
        foreach: planetsToShow,
        beforeRemove: hidePlanetElement,
        afterAdd: showPlanetElement 
    }'
    

    Depending on compatibility you could use css3 transitions as I've done here to give the newly added element a yellow colour that transitions to the normal one after a given timing. (Although the timings and colourings I used need work ;))

    In this fiddle it seems to be working by not applying to the original list, but I guess this might be down to at what stage the observableArray gets modified?

    http://jsfiddle.net/8k8V5/1529/

    0 讨论(0)
  • 2021-02-10 21:58

    If I understand your scenario correctly, then the issue is that the initial time that you populate your observableArray (after binding) you see your highlight. One way to handle a scenario like this would be to use ko.utils.domData or $.data to put a flag on the element to indicate that it is now ready for the highlight effect.

    Something like:

    ko.bindingHandlers.foreachWithHighlight = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
            return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, context);
        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
            var value = ko.unwrap(valueAccessor()),
                key = "forEachWithHightlight_initialized";
    
            var newValue = function () {
                return {
                    data: value,
                    afterAdd: function (el, index, data) {
                        if (ko.utils.domData.get(element, key)) {
                            $(el).filter("li")
                                .animate({
                                backgroundColor: 'yellow'
                            }, 200)
                                .animate({
                                backgroundColor: 'white'
                            }, 800);
                       }
                    }
                };
            };
    
            ko.bindingHandlers.foreach.update(element, newValue, allBindingsAccessor, viewModel, context);
    
            //if we have not previously marked this as initialized and there are currently items in the array, then cache on the element that it has been initialized
            if (!ko.utils.domData.get(element, key) && value.length) {
                ko.utils.domData.set(element, key, true);
            }
    
            return { controlsDescendantBindings: true };
        }
    };
    

    Fiddle here: http://jsfiddle.net/rniemeyer/zGJX3/

    0 讨论(0)
提交回复
热议问题