Give your JS App some Backbone with Models, Views, Collections, and Events

Overview
 ____                     __      __
/\  _`\                  /\ \    /\ \                                   __
\ \ \ \ \     __      ___\ \ \/'\\ \ \____    ___     ___      __      /\_\    ____
 \ \  _ <'  /'__`\   /'___\ \ , < \ \ '__`\  / __`\ /' _ `\  /'__`\    \/\ \  /',__\
  \ \ \ \ \/\ \ \.\_/\ \__/\ \ \\`\\ \ \ \ \/\ \ \ \/\ \/\ \/\  __/  __ \ \ \/\__, `\
   \ \____/\ \__/.\_\ \____\\ \_\ \_\ \_,__/\ \____/\ \_\ \_\ \____\/\_\_\ \ \/\____/
    \/___/  \/__/\/_/\/____/ \/_/\/_/\/___/  \/___/  \/_/\/_/\/____/\/_/\ \_\ \/___/
                                                                       \ \____/
                                                                        \/___/
(_'_______________________________________________________________________________'_)
(_.———————————————————————————————————————————————————————————————————————————————._)

Backbone supplies structure to JavaScript-heavy applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface.

For Docs, License, Tests, pre-packed downloads, and everything else, really, see: http://backbonejs.org

To suggest a feature or report a bug: https://github.com/jashkenas/backbone/issues

For questions on working with Backbone or general discussions: https://groups.google.com/forum/#!forum/backbonejs, http://stackoverflow.com/questions/tagged/backbone.js, or https://gitter.im/jashkenas/backbone

Backbone is an open-sourced component of DocumentCloud: https://github.com/documentcloud

Many thanks to our contributors: https://github.com/jashkenas/backbone/graphs/contributors

Special thanks to Robert Kieffer for the original philosophy behind Backbone. https://github.com/broofa

Comments
  • View hooks for native and non-jQuery libraries

    View hooks for native and non-jQuery libraries

    This is a continuation of the discussion in #2959, and focuses on making View easier to extend by users wishing to use non-jQuery libraries. It's similar in plugability to Backbone.ajax or other overridable parts of Backbone.

    Native Views and non-jQuery DOM libraries would be able to create a native View implementation by overriding $, make, remove, setElement, delegate, and undelegateEvents (see the NativeView reference implementation). This preserves the majority of the public contract of View (with the notable exception of View#$ and view.$el), and the public interface of the constructor (including passing options), delegateEvents/undelegateEvents, render, remove, and setElement would be virtually unchanged. The PR also re-adds View#make.

    The next step would be to remove Backbone.$() calls from History and perhaps extend View#setElement and View#make to use a common exposed createElement utility.


    Update for folks tuning in late: The final list of overridable methods is available on the wiki with instructions for how to use it in your own project.

    enhancement 
    opened by akre54 136
  • Add View#dispose.

    Add View#dispose.

    I've taken another shot at adding a method for cleaning up view references (see #1353). I don't feel particularly strongly about the naming choice though, so please suggest others you think fit better.

    The consensus seems to be that dispose should remove model listeners, remove collection listeners, and undelegate any DOM handlers with undelegateEvents. This seems like it's sufficiently flexible while still providing useful functionality.

    opened by braddunbar 90
  • Query parameters are confusing the router

    Query parameters are confusing the router

    It is not currently possible to use Google Analytics with backbone controlled routes, as the backbone router does not understand query parameters. If I have the routes:

    routes: {
        "": "index",
        ":username": "profile",
    }
    

    then try to route to martyn?utm_source=google&utm_medium=ppc&utm_term=testing, the profile route fires but the username passed is martyn?utm_source=google&utm_medium=ppc&utm_term=testing rather then martyn.

    I saw the discussion on #668. I don't need query parameter support per se, but it would be nice if backbone could be told to ignore query parameters.

    For now I've done (in my own code):

    (function(old) {
        Backbone.History.prototype.getFragment = function() {
            return old.apply(this, arguments).replace(/\?.*/, '');
        };
    })(Backbone.History.prototype.getFragment);
    
    fixed change 
    opened by martynsmith 76
  • Prepare Backbone 1.4

    Prepare Backbone 1.4

    Some significant changes have occurred on master since 1.3. I'd like to get 1.4 out sooner than later. Below are a list of some of the more important activity highlights over the past couple months:

    • Added support for ES6 classes with a preinitialize hook for model creation (https://github.com/jashkenas/backbone/pull/3827). This one should require a good example of how to create an ES6 class extending from BB

    • iterator support https://github.com/jashkenas/backbone/commit/a2fc65b9798d1a5d0dcb43b5c50483640f5187c5

    • Fixed a bug with the hash generation from Router.navigate (#4025)

    • #4131

    /cc @akre54 @jridgewell

    enhancement fixed 
    opened by megawac 75
  • Providing a bare bones convention for nested views

    Providing a bare bones convention for nested views

    The biggest source of questions/complaints/issues I've encountered with Backbone deals with handling the issue of nested views. Any sufficiently complex application (see: real world applications) has a need for managing views within views, and cleaning up after them properly. The (well received) addition of listenTo helps with this to a degree, but I think Backbone could do a bit more.

    This is something I add to pretty much whatever I'm working with, and it does the job without much overhead or complexity:

    var View = Backbone.View;
    Backbone.View = Backbone.View.extend({
    
      constructor: function() {
        this.subviews = [];
        View.apply(this, arguments);
      },
    
      addSubview: function(view) {
        if (!(view instanceof Backbone.View)) {
          throw new Error("Subviews must be a Backbone.View");  
        }
        this.subviews.push(view);
        return view;
      },
    
      removeSubviews: function() {
        var children = this.subviews;
        for (var i = 0, l = children.length; i<l; i++) {
          children[i].remove();
        }
        this.subviews = [];
        return this;
      },
    
      remove: function() {
        this.removeSubviews();
        View.prototype.remove.apply(this, arguments);
      }
    });
    

    I completely understand and agree with Backbone's position to keep things simple and not implement applications specific components; at the same time I think providing a very, very basic starting point for this problem would be a great help to many.

    This starting point could then be extended upon with more opinionated libraries or frameworks like layoutmanager, thorax, marionette, etc.

    /cc @tbranyen

    enhancement wontfix 
    opened by tgriesser 74
  • 1.1.1 breaks browserify

    1.1.1 breaks browserify

    Hello,

    Version 1.1.1 breaks the browserify build of backbone. It's trying to require jQuery although backbone itself doesn't have a dependency on it.

    I know there is a try, catch around it but this doesn't work with browserify it will just try to resolve the require which fails and causes the build to fail.

    bug fixed 
    opened by rthewhite 67
  • Native view and jQuery-less History

    Native view and jQuery-less History

    This PR improves on PR #2865:

    • Adds a very small polyfill of addEventListener and removeEventListener for IE8.
    • Slightly faster, a much more compact and more compatible matchesSelector implementation
    • Fixes a bug with remove where PR#2865 confuses removal with detachment. $.fn.remove will remove event handlers while PR#2865 does not. Failure to do so will make some event handlers depending on this behavior fail. This broke Backgrid.
    • A native setElement that's more faithful to jQuery's behavior. The code is improved from Backbone.native. Specifically, you can supply an HTML snippet, a CSS selector or a DOM element, just like jQuery.
    • No more useNative flag and branching. The old View had been extracted into BaseView and _ensureElement, setElement, delegateEvents and undelegateEvents uses native APIs. So Backbone will have a baseline View that's fast by default.
    • BaseView#$ just delegates to this.el.querySelectorAll and returns a node list.
    • Removes View#find and View#findAll. They add no value and it's not even the correct implementation of the proposed Selectors API Level 2 spec.
    • Introduces _delegateEvents and _undelegateEvents for subclasses to override.
    • Much much more compact implementation of BaseView#_delegateEvent and BaseView#_undelegateEvents in place of util.delegate and util.undelegate. BaseView#_delegateEvent will also work on IE8.
    • Removes the superfluous jQuery shim that's utils. This PR has effectively removes hard dependency on jQuery already by pulling out a BaseView that's basically the old view + 2 hooks and all native DOM API calls. The only remaining dep on $.ajax can be overcome easily by replacing Backbone.ajax with one of the many $.ajax alternative implementations out there.
    • The new Backbone.View is a 26 line extremely light weight subclass of Backbone.BaseView that's 100% backward compatible with the old jQuery-based View.
    • Comments everywhere and better tests.
    • A few less LOC in the Router than #2865 due to the event listener polyfills.

    Tests passed on:

    • IE 8+
    • Chrome
    • Firefox
    • Safari
    • Opera

    Performance:

    http://jsperf.com/backbone-patch-22be8f9/2

    Around 70% faster than the jQuery-based View and slightly faster than #2865, by a couple of percentages consistently.

    Remaining issues:

    • Should BaseView be called something else? Should the native View subclass a refactored jQuery-based View instead? Code size will be exactly the same.
    • IE 8 support in BaseView? See options here.

    cc. @paulmillr @akre54

    enhancement 
    opened by wyuenho 67
  • Unified registration as browser/AMD/CommonJS module.

    Unified registration as browser/AMD/CommonJS module.

    This is an improvement over the #688 based on feedback from @tbranyen and @jdalton. It is a much simpler registration approach.

    One of the simplifications over #688 was to not to try to load jquery in a node/commonjs environment since the current Backbone code does not do that.

    This pull request supersedes #688, I will close 688.

    enhancement wontfix 
    opened by jrburke 60
  • Interested in dropping dependencies on underscore and jQuery?

    Interested in dropping dependencies on underscore and jQuery?

    Zepto is shit. It doesn't even work in IE10 which is pretty modern and used in WP8 smartphones. It also has many strange bugs.

    So, only jQuery is a reasonable library to use with Backbone currently. But it is very big. This increases latency on mobile devices. Totally not cool.

    In Backbone's fork Exoskeleton we (w @akre54) decided to try dropping all dependencies and it worked out very well. Instead of including 40K of gzipped JavaScript, you just need to include 8K — that's five times less! Very noticeable on shitty 2-2.5-3G networks

    But the most important part of dropping jQuery and relying on native methods is the performance. Apps I develop are usually complex and interacting with DOM natively allows to increase speed from 5 to 12 times on Chrome. Proofs are on the website.

    DOM is a total bottleneck and it is unfortunate that jQuery slows it down by several magnitudes. On mobile devices this is even a bigger deal since they are slow.

    Would you be interested in dropping these dependencies? Maybe just jQuery?

    To all folks who may defend the status quo: it's cool. But some users want more freedom.

    How this can look like then:

    question 
    opened by paulmillr 52
  • Re #2976 Allow `id` values to be generated from a function given attrs

    Re #2976 Allow `id` values to be generated from a function given attrs

    Opening for discussion. This commit opens up a generateId function that has the sole job of taking attrs and returning the id value. This makes composite key and nested key support simple.

    fixed change 
    opened by caseywebdev 44
  • Object.observe() integration

    Object.observe() integration

    Since backbone.js is largely built on listening to views, models, collections and other objects (in its own way), the utilization of Object.observe() (thanks to Chrome's 36 stable release) can now be reasonably implemented as a much more manageable and performant (which I'm being told isn't a word) alternative to the underlying .get() / .set() methods we've all come to know and love.

    I'm not proposing to completely do away with anything. Simply, given the presence of an Object.observe()-capable browser, utilize it instead for listening to (and updating/deleting) objects.

    I've looked everywhere for discussion on this topic and it doesn't seem to be on anyone's public posts or pages. I even found a couple of backbone.js add-ons but they're well over 2-3 years old and inactive. However, if I have overlooked something (even something in the master branch here), please point me in the right direction and this issue can be closed.

    Thanks.

    PS - I would love to take this on with a pull if it isn't already being worked on but I don't want to duplicate anyone's current work if I can avoid it.

    question 
    opened by dhenson02 41
  • Separate fetch/save api into plugin or external module

    Separate fetch/save api into plugin or external module

    It would be great if in the second version of the library the model and collection got rid of the built-in backend API. In my opinion, the backend API should be an external module, although it is possible to provide a base implementation. Today, you constantly have to look for workarounds if you want to destroy a model that does not imply synchronization, but has the specified Id. And in general, if we are talking about the model-view concept, in my opinion it would be better if the library will be not aware of the backend Besides, this separation will simplify the process of getting rid of jQuery if such an idea arises.

    question change break 
    opened by taburetkin 17
  • Browser tests that don't work in Sauce labs

    Browser tests that don't work in Sauce labs

    Firefox 11: https://github.com/jashkenas/backbone/runs/4907194010?check_suite_focus=true

    Chrome 26 and 40: https://github.com/jashkenas/backbone/runs/5250001247?check_suite_focus=true#step:6:105

    IE 9 and 10: https://github.com/jashkenas/backbone/runs/5250001247?check_suite_focus=true#step:6:182

    I have disabled these browsers in the karma.conf-sauce.js for the time being, but getting them to run somehow would be desirable.

    starter quality 
    opened by jgonggrijp 0
  • Should Backbone.Collection throw an error when client code attempts to add the same model twice?

    Should Backbone.Collection throw an error when client code attempts to add the same model twice?

    While studying #4249, I found this old comment to another ticket by @jashkenas, in which he writes that Backbone once used to throw an error in this scenario: https://github.com/jashkenas/backbone/issues/2976#issuecomment-33711327.

    If it were up to me, I would prefer that adding duplicate models would throw an error, though I imagine this would be a breaking change for many users.

    That's how it used to be ... and this behavior was an "enhancement" ;)

    It is ambiguous from this comment alone whether the throwing was an "enhancement", or the removal of the throwing. It would not be the first time that a feature is inadvertently removed. If aCollection.add([{id: 1}, {id: 1}]) was supposed to throw (which intuitively makes sense) and this was removed for no good reason, then I suggest reinstating this behavior in the future Backbone 2.0. First, though, we should investigate what happened exactly and why.

    question 
    opened by jgonggrijp 8
  • Embrace prototypes

    Embrace prototypes

    The ES6 class emulation convention doesn't sit well with Backbone, mostly because it provides no convenient way to set non-function prototype properties. In fact, in my opinion, the ES6 class emulation convention doesn't sit well in general for this same reason. On top of that, classes don't sit well with JavaScript, anyway. I'm not the first to say this; consider Walker 2014 and Crockford 2008. I consider #4079 a symptom of classes not sitting well.

    Therefore, in Backbone version 2, rather than adapting the library to ES6 classes, I would like to do away with classes entirely and embrace prototypes instead. That would mean that instead of the following in Backbone 1,

    import { extend } from 'underscore';
    import { Model } from 'backbone';
    
    const CustomModel = Model.extend({
        idAttribute: '_id',
        // ...
    });
    
    // or
    
    class CustomModel extends Model { /*...*/ }
    extend(CustomModel.prototype, {
        idAttribute: '_id',
    };
    
    // in either case:
    const aCustomModelInstance = new CustomModel(attributes, options);
    

    we would be writing something like the following in Backbone 2:

    import { model } from 'backbone';
    
    const customModel = model.extend({
        idAttribute: '_id',
        // ...
    });
    
    const aCustomModelInstance = customModel.construct(attributes, options);
    

    where model is an object that serves as a prototype, instead of a function that emulates a class.

    model.extend(protoprops) (and collection.extend, etcetera) would default to just being a shorthand for Object.create(model, protoprops). (I would likely use _.create instead of Object.create, but that is an implementation detail.) This method can still be overridden by plugins in order to enable things like shorthand syntax at prototype extension time.

    model.construct(attributes, options) would first do Object.create(model) and then perform the same logic on the created instance as the current constructor. In fact, we could retain the old constructor and simply implement model.construct as Object.create(model).constructor(attributes, options). This would enable people who really want to use class emulation to set Model = model.constructor and continue working in the old way.

    In summary, the code would not necessarily change that much. It's just that the library exports prototypes instead of constructors, extend moves from the constructor to the prototype and there is a new construct method that replaces the new keyword. As a result, everyone using Backbone can seamlessly and interchangeably write their code in the same way, regardless of what particular flavor of class emulation they are using.

    Feedback welcome. I'm not starting on Backbone 2 anytime soon, so there is plenty of time.

    question 
    opened by jgonggrijp 12
  • Backbone is being actively maintained

    Backbone is being actively maintained

    2021-12-14 update by @jgonggrijp: I'll be maintaining Backbone. You can skip to this comment for the latest news.

    As this project seems to be dead: is there a still maintained fork?

    fixed quality 
    opened by chkpnt 20
Owner
Jeremy Ashkenas
🏍 🛣 🌎 I miss _why.
Jeremy Ashkenas
App development framework based on cocos creator3.1.1

todo: Waiting for English translation cx-cocos App development framework based on cocos creator3.1.1 一个基于cocos creator3.1.1的应用App和游戏开发框架 关键词:cocos cre

null 63 Dec 7, 2022
The official web app of OwnStore suite.

This project is part of OwnStore suite. Learn more here: https://ownstore.dev The suite contains the following projects: Website API CMS Doc Apps TWA

OwnStore 32 Dec 19, 2022
Boilerplate starter template for a new Telegram Web App (TWA) interacting with the TON blockchain

TON Starter Template - Telegram Web App (TWA) Starter template for a new TWA interacting with the TON blockchain Overview This project is part of a se

TON @ DeFi.org 11 Dec 17, 2022
A rugged, minimal framework for composing JavaScript behavior in your markup.

Alpine.js Alpine.js offers you the reactive and declarative nature of big frameworks like Vue or React at a much lower cost. You get to keep your DOM,

Alpine.js 22.5k Jan 2, 2023
OpenUI5 lets you build enterprise-ready web applications, responsive to all devices, running on almost any browser of your choice.

OpenUI5. Build Once. Run on any device. What is it? OpenUI5 lets you build enterprise-ready web applications, responsive to all devices, running on al

SAP 2.7k Dec 31, 2022
Custom Elements Manifest is a file format that describes custom elements in your project.

@custom-elements-manifest Custom Elements Manifest is a file format that describes custom elements. This format will allow tooling and IDEs to give ri

open-wc 131 Dec 15, 2022
A small jQuery plugin that will automatically cast a shadow creating depth for your flat UI elements

#Flat Shadow by Pete R. A small jQuery plugin that will automatically cast a shadow creating depth for your flat UI elements Created by Pete R., Found

Pete R. 482 Dec 18, 2022
Turbolinks makes navigating your web application faster

Turbolinks is no longer under active development Please note that Turbolinks is no longer under active development. It has been superseded by a new fr

Turbolinks 12.8k Jan 4, 2023
🌱 React and redux based, lightweight and elm-style framework. (Inspired by elm and choo)

English | 简体中文 dva Lightweight front-end framework based on redux, redux-saga and react-router. (Inspired by elm and choo) Features Easy to learn, eas

null 16.1k Jan 4, 2023
A declarative, efficient, and flexible JavaScript library for building user interfaces.

React · React is a JavaScript library for building user interfaces. Declarative: React makes it painless to create interactive UIs. Design simple view

Facebook 200k Jan 4, 2023
A blazing fast React alternative, compatible with IE8 and React 16.

Nerv is a virtual-dom based JavaScript (TypeScript) library with identical React 16 API, which offers much higher performance, tinier package size and

null 5.4k Jan 4, 2023
Write JSX-driven components with functions, promises and generators.

Crank.js Write JSX-driven components with functions, promises and generators. Documentation is available at crank.js.org. Crank.js is in a beta phase,

null 2.5k Jan 1, 2023
The simplest way to create web components from plain objects and pure functions! 💯

?? One of the four nominated projects to the "Breakthrough of the year" category of Open Source Award in 2019 hybrids is a UI library for creating web

hybrids 2.7k Dec 27, 2022
Simple and elegant component-based UI library

Simple and elegant component-based UI library Custom components • Concise syntax • Simple API • Tiny Size Riot brings custom components to all modern

Riot.js 14.7k Jan 4, 2023
A functional and reactive JavaScript framework for predictable code

Cycle.js A functional and reactive JavaScript framework for predictable code Website | Packages | Contribute | Chat | Support Welcome Question Answer

Cycle.js 10.2k Jan 4, 2023
A Web Component compiler for building fast, reusable UI components and static site generated Progressive Web Apps

Stencil: A Compiler for Web Components and PWAs npm init stencil Stencil is a simple compiler for generating Web Components and static site generated

Ionic 11.3k Jan 4, 2023
A declarative, efficient, and flexible JavaScript library for building user interfaces.

Solid is a declarative JavaScript library for creating user interfaces. It does not use a Virtual DOM. Instead it opts to compile its templates down t

Ryan Carniato 24.5k Jan 4, 2023
Re-developed the Sky Ice Cream website using ReactJS. Redesigned the UI to a much more appealing and intuitive styling.

This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: npm start Runs the app in the developmen

Aakash Jana 1 Dec 27, 2021