Bridge for using Backbone or Marionette with Polymer library.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
test
.eslintrc
.gitignore
LICENSE
README.md
bower.json
manifest.json
polymer.json

README.md

Backbone Model for Polymer

Published on webcomponents.org

This simple library that provides Backbone Model for Polymer Custom Elements.

Polymer is a JavaScript library that helps you create custom reusable HTML elements, and use them to build performant, maintainable apps. https://www.polymer-project.org/

Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control. You extend Backbone.Model with your domain-specific methods, and Model provides a basic set of functionality for managing changes. http://backbonejs.org/#Model

Two classes have been created to add binding with model. Namely PolymerModel which extends normal Backbone.Model and PolymerModelBindingMixin that provides bindings for Custom Elements.

Sample usage

Custom element code:

<link rel="import" href="src/model/model-binding-mixin.html">
<link rel="import" href="bower_components/polymer/polymer-element.html">

<dom-module id="my-element">
    <template>
        <label for="first-name">First name</label>
        <input type="text" name="first_name" id="first-name" value="{{model.firstName::change}}">
        <label for="last-name">Last name</label>
        <input type="text" name="last_name" id="last-name" value="{{model.lastName::change}}">
    </template>
    <script>
        class MyElement extends PolymerModelBindingMixin(Polymer.Element) {
            static get is() {
                return 'my-element';
            }
        }
    
        window.customElements.define(MyElement.is, MyElement);
    </script>
</dom-module>

Code placed somewhere on the website:

<link rel="import" href="my-element.html">
<my-element id="foo"></my-element>
<script>
    const element = document.querySelector('#foo');
    const model = new PolymerModel();
    model.attachElement(element);
    model.set('firstName', 'John');
</script>

When you change firstName property on the model, then input inside shadow root is updated and vice versa also.

Backbone.View inside Element

You can use the Backbone.View inside Element. To create a view for element use mixin PolymerViewMixin(elementClass, viewClass).

Element with Backbone.View:

class XButtonCounterView extends Backbone.View {
    events() {
        return {
            'click .counter__button': '_onClickButton',
        };
    }
    initialize(options) {
        /** @type {XButtonCounter} */
        this._element = options.element;
    }
    _onClickButton(e) {
        this._element.increase();
    }
}

class XButtonCounter extends PolymerViewMixin(Polymer.Element, XButtonCounterView) {
    static get is() {
        return 'x-button-counter';
    }
    static get properties() {
        return {
            count: {
                type: Number,
                value: 0,
            },
        };
    }
    increase() {
        this.count++;
        // You have access to the view
        // this.view.$el - access to element main container
    }
}

Marionette.View inside Element

PolymerViewMixin it also works with Marionette Views.

Element with Mn.View:

class XModalView extends Mn.View {
    ui() {
        return {
            close: '.modal__close',
        };
    }
    events() {
        return {
            'click @ui.close': '_onClickClose',
        };
    }
    initialize(options) {
        /** @type {XModal} */
        this._element = options.element;
    }
    _onClickClose(e) {
        this._element.close();
    }
}

class XModal extends PolymerViewMixin(Polymer.Element, XModalView) {
    static get is() {
        return 'x-modal';
    }
    static get properties() {
        return {
            opened: {
                type: Boolean,
                value: false,
            },
        };
    }
    open() {
        this.setAttribute('opened', 'opened');
        // You have access to the view
        // this.view.$el - access to element main container
        // this.view.getUI('close') - access to close button element
    }
    close() {
        this.removeAttribute('opened');
    }
}