rivets-bfeach-binder.js 3.8 KB
define(function(require) {
    'use strict';
    var Backbone = require('backbone');
    var rivets = require('rivets');
    var BackboneModelOverlay = require('backbone-model-overlay');

    var bfEachUtil = {
        getIterator: function getIterator(adapter) {
            return adapter.iterate || function iterate(obj, cb) {
                obj = obj || [];
                var i;
                for (i = 0; i < obj.length; i++) {
                    cb(obj[i], i);
                }
            };
        },
    };
    (function(rivetsBinders) {
        rivetsBinders['bfeach-*'] = {
            block: true,
            bind: function(el) {
                var insertionPoint = this.insertionPoint;
                if (this.insertionPoint === undefined) {
                    var type = this.type, parentNode = el.parentNode;
                    this.insertionPoint = insertionPoint = document.createComment(' rivets: ' + type + ' ');
                    el.removeAttribute([this.view.prefix, type].join('-').replace('--', '-'));
                    this.subItems = [];
                    parentNode.insertBefore(insertionPoint, el);
                    parentNode.removeChild(el);
                } else {
                    var i;
                    var subItems = this.subItems;
                    for (i = 0; i < subItems.length; i++) {
                        subItems[i].view.bind();
                    }
                }
            },
            unbind: function(el) {
                var i;
                var subItems = this.subItems;
                for (i = 0; i < subItems.length; i++) {
                    subItems[i].view.unbind();
                }
            },
            routine: function(el, value) {
                var parentView = this.view;
                var observer = this.observer;
                var adapters = observer.options.adapters;
                var iterate = bfEachUtil.getIterator(adapters[observer.key.i]);

                var rootInterface = observer.tokens.length ? observer.tokens[0].i : observer.key.i;
                var modelName = this.args[0];
                var iterationAlias = rivets.iterationAlias(modelName);
                var subItems = this.subItems;
                var insertionPoint = this.insertionPoint;
                var newItemCount = 0;
                iterate(value, function(value, index) {
                    var subItem = subItems[index];
                    var subData = {};
                    subData[modelName] = value;
                    subData['index'] = index;
                    subData[iterationAlias] = index;
                    if (subItem === undefined) {
                        var clonedEl = el.cloneNode(true);
                        subItem = {model: new BackboneModelOverlay(subData, {parent: parentView.models}), el: clonedEl};
                        var options = parentView.options();
                        options.preloadData = true;
                        //options.adapters = bfEachUtil.makeOverrideAdapters(options.adapters, subData);
                        subItem.view = rivets.bind(clonedEl, subItem.model, options);
                        subItems.push(subItem);
                        insertionPoint.parentNode.insertBefore(clonedEl, insertionPoint.nextSibling);
                    } else {
                        subItem.model.set(subData, {overlay: true});
                    }
                    insertionPoint = subItem.el;
                    newItemCount++;
                });
                while (subItems.length > newItemCount) {
                    var extraItem = subItems.pop();
                    extraItem.view.unbind();
                    extraItem.el.parentNode.removeChild(extraItem.el);
                }
            },
            // update function not needed
        };
    })(rivets.binders);
    return bfEachUtil;
});