npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

backbone-relation

v0.3.0

Published

Simple support for relations for Backbone models

Downloads

169

Readme

backbone-relation

Build Status Coverage Status

Backbone does not support relations by default. This is a simple package that adds relations to Backbone.

The idea is simple: you can define relations like you define defaults. A relation can be either a Model or a Collection and attributes can be set recursively through the parent.

Why use this over backbone-relational? We found backbone-relational too complex. Itʼs basically an ORM in the frontend. We didnʼt need that, hence this package.

Vision

  • 100% compatible with original Backbone codebase. All Backbone test must pass when tested using backbone-relation.
  • Extend Backbone, don't patch it.
  • Make it clear. Only add well defined and tested features, leaving as little as possible open to interpretation.

Use case

Imagine an API-endpoint gives the following response when hitting api/user/1:

{
    id: 1,
    username: 'witchhunter',
    profile: {
        id: 7,
        first_name: 'Michelle',
        last_name: 'Velvet'
    }
}

You can define 2 models, one called MProfile and the other MUser:

MProfile = MRelation.extend();

MUser = MRelation.extend({
    relations: {
        profile: MProfile
    }
})

Now you can do a fetch and the profile model will be filled with data on the user model:

mUser = new MUser({id: 1});
mUser.fetch();

... 

mUser.get('profile').get('first_name'); // 'Michelle'

When setting data, you can do the following:

mUser.set({
    profile: {first_name: 'Vera'}
});

mUser.get('profile').get('first_name'); // 'Vera'

Defining relations

You can define relations using the relations attribute. It can either be a hash or a function that returns a hash. There are a few different ways to define relations:

Simple

The simplest form without any options. Example:

var MAuthor = Model.extend({
    relations: {
        // This is a simple relation where MUser is a Model.
        user: MUser,

        // Here we define an attribute which should be a collection.
        posts: CPost,
    }
})

Advanced

With this form you can add a bit more configuration options. These are the options at the moment:

| Key | Description | | --- | ----------- | | relationClass | The constructor for the relation. This can either be a Backbone.Model or a Backbone.Collection.

Example:

var MAuthor = Model.extend({
    relations: {
        // Similar to posts, just another syntax. This supports more complex configuration options.
        contacts: {relationClass: CContact}
    }
})

Setting related data

The most basic form of setting a related data is getting it first:

mAuthor.get('user').set('id', 17);
mAuthor.get('contacts').set([{id: 1}, {id: 2}]);

Another way of setting related data is using the attribute name on the parent. These lines do exactly the same:

mAuthor.get('user').set('id', 17);
mAuthor.set('user', {id: 17});
mAuthor.set({user: {id: 17}});

This implies that once a relation is set, it cannot be overridden with another value. If you do really want to set another instance for a relation, then first use unset:

mAuthor.unset('user');
mAuthor.set('user', mUser);

Bottom line: if a relation exists, set is proxied.

Getting related data

You can use vanilla Backbone to get related data:

mAuther.get('user'); // -> Instance of MUser.
mAuther.get('user').get('id') // -> Get the id of the related user.

Model.dot

Shorthand for getting nested attributes. Example:

model
    .get('nestedModel1')
    .get('nestedCollection2')
    .get('nestedIdOfModel3')
    .get('foo');

can be written like:

model.dot('nestedModel1.nestedCollection2.nestedIdOfModel3.foo');

This depends on that the nested relation has a get function defined. That function is called each time a dot is found. If you try to use dot on a value that does not have the function get defined, it will return undefined.

Returns undefined because of someString is a string without a get function defined:

model.dot('nestedModel1.someString.foo.bar');

Returns undefined because of object is an object without a get function defined:

model.dot('nestedModel1.object.foo.bar');

Returns undefined because of nonExistingModelOrCollection is undefined and thus without a get function defined:

model.dot('nestedModel1.nonExistingModelOrCollection.foo.bar');

Returns undefined because of nonExistingId is undefined and thus without a get function defined:

model.dot('nestedCollection1.nonExistingId.foo.bar');

Itʼs not possible to retrieve attributes with a . in the name. You can use get instead:

model.dot('nestedModel1.nestedCollection2.nestedIdOfModel3').get('foo.bar');

Options

| Key | Default | Description | | --- | ------- | ----------- | | createRelations | true | true: create relations while initializing model. false: skip creating relations upon initialization. |