GithubHelp home page GithubHelp logo

backbone.babysitter's Introduction

Backbone.BabySitter

Build Status

Manage child views in a Backbone.View.

About Backbone.BabySitter

Backbone provides a lot of functionality in its views, but does not directly provide a way to manage child views or nested views. This is not terribly difficult to do on your own, but it gets tedious to write the same code over and over again.

Backbone.BabySitter provides a simple way to manage an unknown number of child views within a Backbone.View, or other object that needs to track a list of views.

Downloads And Source

Grab the source from the src folder above. Grab the most recent builds from the links below.

Documentation

Backbone.BabySitter exposes one constructor function: Backbone.ChildViewContainer. This constructor function contains all of the necessary code for managing a list of views.

Storing Views

Views can be added to a container by calling the add method:

var container = new Backbone.ChildViewContainer();

container.add(someView);
container.add(anotherView);

Views will be stored once and indexed in several ways:

  • by view.cid
  • by view.model.cid if the view has a model
  • by a custom index key

When adding a view, you can optionally specify a custom index key by which you can later retrieve the view.

container.add(aView, "an indexer");

Note that the custom indexer should be unique within the container. If you add two different views with the same custom indexer, the last one in will be the only one stored by that index key.

Constructing With Views

An initial list of views can be added to the container through the constructor function call. This list must be an array of view instances:

var views = [someView, anotherView];
var container = new Backbone.ChildViewContainer(views);

Retrieving Views

You can retrieve a view by any of the index:

var container = new Backbone.ChildViewContainer();

container.add(someView);
container.add(anotherView);
container.add(collectionView);
container.add(aView, "an indexer");

// find by view cid
var s = container.findByCid(someView.cid);

// find by model
var av = container.findByModel(anotherView.model);

// find by model cid
var av2 = container.findByModelCid(anotherView.model.cid);

// find by custom key
var custv = container.findByCustom("an indexer");

// find by numeric index (unstable)
var custv = container.findByIndex(0);

If the findBy* method cannot find the view, it will return undefined.

Removing A View

You can remove a view directly and it will be removed from all available indexes.

var container = new Backbone.ChildViewContainer();

container.add(view);

// some time later
container.remove(view);

To remove a view by an index, find it by that index and then remove the resulting view.

Executing Methods On All Views

You can execute any arbitrary method with any arbitrary parameters on all of the views within the container. There are two ways to do this: container.call and container.apply. These methods work similarly to function.call and function.apply in how parameters are passed through. However, they do not allow the context to be specified. The view on which a method is being called will always be the context of the call.

var View = Backbone.View.extend({
  doStuff: function(a, b){
  },

  moreStuff: function(a, b){
  }
});

var v1 = new View();
var v2 = new View();

var container = new Backbone.ChildViewContainer();
container.add(v1);
container.add(v2);

// call the doStuff function
container.call("doStuff", 1, 2);

// apply the doStuff function
container.apply("doStuff", [1, 2]);

If any given view within the container does not have the method specified, it will not be called on that view. No errors will be thrown in this situation.

Get The Number Of Stored Views

To get the number of stored views, call the container.length attribute. This attribute is updated any time a view is added or removed.

var container = new Backbone.ChildViewContainer();

container.add(view);
container.add(v2);
container.add(v3);

console.log(container.length); //=> 3

container.remove(v2);

console.log(container.length); //=> 2

Iterators And Collection Functions

The container object borrows several functions from Underscore.js, to provide iterators and other collection functions, including:

  • forEach
  • each
  • map
  • reduce
  • find
  • detect
  • filter
  • select
  • reject
  • every
  • all
  • some
  • any
  • include
  • contains
  • invoke
  • toArray
  • first
  • initial
  • rest
  • last
  • without
  • isEmpty
  • pluck

These methods can be called directly on the container, to iterate and process the views held by the container.

var container = new Backbone.ChildViewContainer();

container.add(v1);
container.add(v2);
container.add(v3);

// iterate over all of the views
container.each(function(view){

  // process each view individually, here

});

For more information about these methods, see the Underscore.js documentation.

ChangeLog

For a complete change log, see the CHANGELOG.md file.

License

MIT - see LICENSE.md

Dev

  • npm install
  • npm install -g grunt-cli
  • grunt

backbone.babysitter's People

Contributors

ahumphreys87 avatar ath0mas avatar calamari avatar cobbweb avatar danrpts avatar denar90 avatar dgbeck avatar drgrey87 avatar fantactuka avatar garethadavies avatar garrison avatar go-oleg avatar gurdotan avatar hashchange avatar jamesplease avatar jamiebuilds avatar jdreesen avatar justblackbird avatar kis avatar marcelklehr avatar megawac avatar paulfalgout avatar paulyoder avatar rafde avatar samccone avatar wbinnssmith avatar xmartin avatar zerkalica avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

backbone.babysitter's Issues

Why package.json has different dependencies with bower.json?

package.json:
"dependencies": { "backbone": ">=0.9.9 <=1.3.2", "underscore": ">=1.4.0 <=1.8.3" },

bower.json:
"dependencies": { "backbone": ">=0.9.9 <=1.2.3", "underscore": ">=1.4.0 <=1.8.3" },
P.S. The same problem in backbone.wreqr library, that's why i can't use backbone v.1.3.2

Publish version 0.0.6 in Jam Package Manager

Hello,

Jam lists version 0.0.5 of backbone.babysitter and I'd be happy to see the latest one available - 0.0.6 at the moment.
I'd be happy to help pushing this version - but only one of the owners can do it on jam.

Regards,

Ludovic LANGE

Update tag to avoid mismatch errors

Looks as though v0.1.12 contains a bower.json that marks it as v0.1.11. This in itself is not too much of an issue as only results in:
bower backbone.babysitter#* mismatch Version declared in the json (0.1.11) is different than the resolved one (0.1.12)

However, since v0.1.11 has a different version dependency of Backbone, it actually ends up using Backbone v1.2.3 (as defined in v0.1.11 bower.json) rather than the Backbone v1.3.3 (as defined in v0.1.12)
I hope that it is easy to update the tag and correct the version that bower downloads?

Thanks,,

Just Storage?

This doesn't render any views, correct? It's just a means of storage for views?

Please publish this version

Please keep backbone / jquery version dependencies in sync with backbone.marionette.

It's very important for those using npm like with browserify otherwise multiple backbone will be used and babysitter will be attached to one backbone, but marionette to another and marionette will have an undefined backbone.babysitter.

Update peerDependencies

We should update the peerDependencies for babysitter for the Mn v3 release. I think we can get away with possibly setting less restrictions on this library that maybe we would for Mn.

Possibly just:

"peerDependencies": {
    "backbone": "^1.3.3",
    "underscore": "^1.8.3"
  }

Since they're peer Deps anyone could still install older versions, but it would just complain on npm i.

Release 0.1.13

Needed to fix bower. Also we need to make sure the build file version gets updates as well.. That looks manual and it still says 0.1.11.

TypeError: Object #<Object> has no method '_updateLength'

Something is wrong with this lib (or with me), I can't make it work, trying to use it with my project without marionette, using require.js to load, but I get the following error.

the main.js file looks like this:

requirejs.config({
  paths: {
    'underscore': 'lib/underscore',
    'backbone': 'lib/backbone',
    'backbone.babysitter': 'lib/backbone.babysitter',
    'jquery': 'lib/jquery',
  },
  shim: {
    underscore: {
      exports: '_'
    },
    backbone: {
      deps: ['underscore','jquery'],
      exports: 'Backbone'
   }
  }
});

and where I want to use:

require( ['backbone.babysitter'], function(){
  var v = Backbone.ChildViewContainer();
});

debugging the code I find that the _updateLength() is added to the Container.prototype , while this in

var Container = function(views){
    this._views = {};
    this._indexByModel = {};
    this._indexByCustom = {};
    this._updateLength();
    _.each(views, this.add, this);
  };

refers to Backbone.ChildViewContainer

What's going on here?

Apply method, IE8- bug

IE8- doesn't accept undefined as valid second parameter for Function#apply method.
Working solution should be change one line in Container#apply to: view[method].apply(view, args || []);

Deprecate backbone.babysitter

We've integrated babysitter into Mn directly (thanks to @paulfalgout). Do we need to continue support this babysitter as separate lib?
@marionettejs/marionette-core any things?

Version range for Backbone invalid in bower.json, installs wrong version

In bower.json, the Backbone version range has been defined as ">=0.9.9 <=1.3.x". The <=1.3.x part is not resolved as one would expect, and installs a 1.2.x version. So we get Backbone 1.2.3 instead of the latest 1.3.x.

You can either make it >=0.9.9 <1.4 or set the range as 0.9.9 - 1.3.x. Both work.

A way to reach variable in loop - JSLint

Hey all,

I have a function like this in the example:

container.each(function(view){
      // process each view individually, here
});

Is there a way to reach 'view' without declaring a function in the loop? I'm trying to make my code JSLint compliant, and I can't figure out if there's a solution to this.

Add a new retrieve method 'findByModelId'

I have a desire to find a view by its underlying model's id. Backbone allows you specify the value of this with the idAttribute in order to store a unique key relevant to a back-end service.

I realize I could achieve this by essentially doing:

container.add(aView, "id");

However, using Marionette's CompositeView or CollectionView, the container's add is called within an function that isn't easily overridden (and don't really want to).

addItemView: function(item, ItemView, index){
  var itemViewOptions = Marionette.getOption(this, "itemViewOptions");
  if (_.isFunction(itemViewOptions)){
    itemViewOptions = itemViewOptions.call(this, item, index);
  }

  var view = this.buildItemView(item, ItemView, itemViewOptions);

  this.addChildViewEventForwarding(view);

  this.triggerMethod("before:item:added", view);

  this.children.add(view);

  this.renderItemView(view, index);

  if (this._isShown){
     Marionette.triggerMethod.call(view, "show"):
  }

  this.triggerMethod("after:item:added", view);
},

Since, the 'id' attribute of the model is defined by Backbone, I think it would worthwhile to add the capability to find the view by the attribute if defined.

I think this could easily be achieved by simply adding a new index object.

this._indexByModelId = {};

add: function(view, customIndex){

  ...

  // index it by model
  if (view.model){

    ...

    // add index by model id if present
    if(view.model.id) {
      this._indexByModelId[view.model.id] = viewCid;
    }
  }

  ...

}

...

findByModelId: function(modelId){
  var viewCid = this._indexByModelId[modelId];
  return this.findByCid(viewCid);
},

...

No reuse of child-view closing

It seems to me that the backbone babysitter should listen for close events on the parent view, enabling any user of the babysitter to take advantage of complete sub-view lifecycle. It's great to have that lifecycle management in CollectionView and CompositeView, and it would be even better to be able to harness it for other cases.

Would you accept a patch that refactors the ChildViewContainer and the CollectionView to move the child-view closing responsibility to the ChildViewContainer, perhaps by passing it an optional parent view in the second arg to the constructor? Or will it be necessary to have a separate entity responsible for child-view closing (e.g. due to memory-management issues)?

Add dependencies to bower.json

When using ck86/main-bower-files to load marionette, the load order is broken because babysitter doesn't have its dependencies properly declared, loading it before Backbone. Adding the dependencies solves the problem.

-- snip --
"dependencies": {
"backbone": ">=0.9.9 <=1.1.2",
"underscore": ">=1.3.3 <=1.6.0"
},
-- /snip --

Model's index in a collection doesn't match itemView index in .children collection

Say I have a collection of models like this one:

var itemsCollection = new Backbone.Collection([{name: 'item1'}]);

And a collection view:

var itemsView = new Marionette.CollectionView({
    collection: itemsCollection, 
    itemView: Marionette.View
});

Then I add a new item into the collection at index 0

itemsCollection.add({name: 'item0'}, {at:0});

Now itemsView is going to create a new item view with the new model {name: 'item0'} but the problem is that it will not get indexed with 0 in the children collection

So if I called itemsView.children.findByIndex(0) I will get back the view that has the model {name: 'item1'} instead of the one that has {name: 'item0'}

I can get around this issue if I do itemsView.children.findByModel(itemsView.collection.at(0)) but I was hopping itemsView.children.findByIndex(0) could just work

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.