Knockoutjs foreach custom bindinghandler with afterAdd

左心房为你撑大大i 提交于 2019-12-03 08:31:26

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/

Stephen James

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/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!