/nextbone

Backbone reimagined with ES classes and web components

Primary LanguageJavaScriptMIT LicenseMIT

Nextbone

Nextbone is a conversion of venerable Backbone using modern Javascript features. It also replaces the View layer by a set of utilities to integrate with Web Components.

Features

  • Keeps Backbone features / behavior with minimal changes. In fact, most of the code is untouched
  • Uses EcmaScript Modules and Classes
  • Fully tree shackable
  • Seamless integration with Web Components (specially LitElement)

Install

$ npm install nextbone

To take fully advantage of nextbone is necessary to use Typescript or Babel configured with @babel/plugin-proposal-decorators and @babel/plugin-proposal-class-properties plugins

Usage

Examples uses language features (class properties and decorators) that needs transpiling with Babel or Typescript

Define models

import { Model, Collection } from 'nextbone'

class Task extends Model {
  static defaults  = {
    title: '',
    done: false
  }
}

class Tasks extends Collection {
  static model = Task
}

const tasks = new Tasks()
tasks.fetch()

Define a web component using LitElement

Without decorators

import { LitElement, html} from 'lit'
import { view, delegate } from 'nextbone'

class TasksView extends view(LitElement) {
  static properties = {
    // set type hint to `Collection` or `Model` to enable update on property mutation
    tasks: { type: Collection }
  }

  constructor() {
    super()
    this.tasks = new Tasks()
    delegate(this, 'click', '#fetch', this.fetchTasks)
  }

  fetchTasks() {
    this.tasks.fetch()
  }

  render() {
    return html`
    <h2>Tasks</h2>
    <ul>
      ${tasks.map(task => {
        html`<li>${task.get('title')}</li>`
      })}
    </ul>
    <button id="fetch">Fetch data</button>
    `
  }
}

customElements.define('tasks-view', TasksView)

document.body.innerHTML = '<tasks-view></tasks-view>'

With decorators

import { LitElement, html, property } from 'lit'
import { state, eventHandler } from 'nextbone'

@view
class TasksView extends LitElement {
  // use specialized `state` decorator
  @state
  tasks = new Tasks()

  // or use `property` decorator with type hint = `Collection` or `Model`
  @property({ type: Collection })
  tasks = new Tasks()

  @eventHandler('click', '#fetch')
  fetchTasks() {
    this.tasks.fetch()
  }

  render() {
    return html`
    <h2>Tasks</h2>
    <ul>
      ${tasks.map(task => {
        html`<li>${task.get('title')}</li>`
      })}
    </ul>
    <button id="fetch">Fetch data</button>
    `
  }
}

customElements.define('tasks-view', TasksView)

document.body.innerHTML = '<tasks-view></tasks-view>'

Documentation

WIP

Related projects

Copyright © 2019-2024 Luiz Américo Pereira Câmara