{"id":15630575,"url":"https://github.com/afeld/backbone-nested","last_synced_at":"2025-05-16T16:06:10.079Z","repository":{"id":2135132,"uuid":"3078628","full_name":"afeld/backbone-nested","owner":"afeld","description":"A plugin to make Backbone.js keep track of nested attributes - looking for maintainers! https://github.com/afeld/backbone-nested/issues/157","archived":false,"fork":false,"pushed_at":"2020-12-02T15:20:01.000Z","size":10119,"stargazers_count":442,"open_issues_count":44,"forks_count":83,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-05-04T00:01:51.207Z","etag":null,"topics":["backbone","backbone-models","nested-attributes"],"latest_commit_sha":null,"homepage":"https://afeld.github.com/backbone-nested/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/afeld.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-12-31T07:10:07.000Z","updated_at":"2025-03-04T11:01:37.000Z","dependencies_parsed_at":"2022-09-10T23:55:22.289Z","dependency_job_id":null,"html_url":"https://github.com/afeld/backbone-nested","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afeld%2Fbackbone-nested","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afeld%2Fbackbone-nested/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afeld%2Fbackbone-nested/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afeld%2Fbackbone-nested/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/afeld","download_url":"https://codeload.github.com/afeld/backbone-nested/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235686,"owners_count":22036962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backbone","backbone-models","nested-attributes"],"created_at":"2024-10-03T10:33:27.557Z","updated_at":"2025-05-16T16:06:10.059Z","avatar_url":"https://github.com/afeld.png","language":"JavaScript","readme":"# Backbone-Nested [![Build Status](https://secure.travis-ci.org/afeld/backbone-nested.png?branch=master)](http://travis-ci.org/afeld/backbone-nested)\n\nA plugin to make [Backbone.js](http://documentcloud.github.com/backbone) keep track of nested attributes.  Download the latest version and see the changelog/history/release notes on the [Releases](https://github.com/afeld/backbone-nested/releases) page.  **Supports Backbone 0.9.x and 1.x.**\n\n## The Need\n\nSuppose you have a Backbone Model with nested attributes, perhaps to remain consistent with your document-oriented database.  Updating the nested attribute won't cause the model's `\"change\"` event to fire, which is confusing.\n\n```javascript\nvar user = new Backbone.Model({\n  name: {\n    first: 'Aidan',\n    last: 'Feldman'\n  }\n});\n\nuser.bind('change', function(){\n  // this is never reached!\n});\n\nuser.get('name').first = 'Bob';\nuser.save();\n```\n\nWouldn't it be awesome if you could do this?\n\n```javascript\nuser.bind('change:name.first', function(){ ... });\n```\n\n## Installation\n\n### [Bower](http://bower.io/)\n\nRecommended.\n\n1. Install the latest version:\n\n    ```bash\n    bower install backbone backbone-nested-model jquery underscore --save\n    ```\n\n2. Add `backbone-nested.js` to your HTML `\u003chead\u003e`:\n\n    ```html\n    \u003c!-- must loaded in this order --\u003e\n    \u003cscript type=\"text/javascript\" src=\"/bower_components/jquery/jquery.js\"\u003e\u003c/script\u003e\n    \u003cscript type=\"text/javascript\" src=\"/bower_components/underscore/underscore.js\"\u003e\u003c/script\u003e\n    \u003cscript type=\"text/javascript\" src=\"/bower_components/backbone/backbone.js\"\u003e\u003c/script\u003e\n    \u003cscript type=\"text/javascript\" src=\"/bower_components/backbone-nested-model/backbone-nested.js\"\u003e\u003c/script\u003e\n    ```\n\n### Manual\n\nDownload the latest [release](https://github.com/afeld/backbone-nested/releases) and the dependencies listed above, then include with script tags in your HTML.\n\n## Usage\n\n1. Change your models to extend from `Backbone.NestedModel`, e.g.\n\n    ```javascript\n    var Person = Backbone.Model.extend({ ... });\n    \n    // becomes\n    \n    var Person = Backbone.NestedModel.extend({ ... });\n    ```\n\n2. Change your getters and setters to not access nested attributes directly, e.g.\n\n    ```javascript\n    user.get('name').first = 'Bob';\n    \n    // becomes\n    \n    user.set({'name.first': 'Bob'});\n    ```\n\nBest of all, `Backbone.NestedModel` is designed to be a [backwards-compatible](http://afeld.github.com/backbone-nested/test/), drop-in replacement of `Backbone.Model`, so the switch can be made painlessly.\n\n## Nested Attributes\n\n`get()` and `set()` will work as before, but nested attributes should be accessed using the Backbone-Nested string syntax:\n\n### 1-1\n\n```javascript\n// dot syntax\nuser.set({\n  'name.first': 'Bob',\n  'name.middle.initial': 'H'\n});\nuser.get('name.first') // returns 'Bob'\nuser.get('name.middle.initial') // returns 'H'\n\n// object syntax\nuser.set({\n  'name': {\n    first: 'Barack',\n    last: 'Obama'\n  }\n});\n```\n\n### 1-N\n\n```javascript\n// object syntax\nuser.set({\n  'addresses': [\n    {city: 'Brooklyn', state: 'NY'},\n    {city: 'Oak Park', state: 'IL'}\n  ]\n});\nuser.get('addresses[0].state') // returns 'NY'\n\n// square bracket syntax\nuser.set({\n  'addresses[1].state': 'MI'\n});\n```\n\n## Events\n\n### \"change\"\n\n`\"change\"` events can be bound to nested attributes in the same way, and changing nested attributes will fire up the chain:\n\n```javascript\n// all of these will fire when 'name.middle.initial' is set or changed\nuser.bind('change', function(model, newVal){ ... });\nuser.bind('change:name', function(model, newName){ ... });\nuser.bind('change:name.middle', function(model, newMiddleName){ ... });\nuser.bind('change:name.middle.initial', function(model, newInitial){ ... });\n\n// all of these will fire when the first address is added or changed\nuser.bind('change', function(model, newVal){ ... });\nuser.bind('change:addresses', function(model, addrs){ ... });\nuser.bind('change:addresses[0]', function(model, newAddr){ ... });\nuser.bind('change:addresses[0].city', function(model, newCity){ ... });\n```\n\n### \"add\" and \"remove\"\n\nAdditionally, nested arrays fire `\"add\"` and `\"remove\"` events:\n\n```javascript\nuser.bind('add:addresses', function(model, newAddr){ ... });\nuser.bind('remove:addresses', function(model, oldAddr){ ... });\n```\n\n## Special Methods\n\n### add()\n\nActs like `set()`, but appends the item to the nested array.  For example:\n\n```javascript\nuser.get('addresses').length; //=\u003e 2\nuser.add('addresses', {\n  city: 'Seattle',\n  state: 'WA'\n});\nuser.get('addresses').length; //=\u003e 3\n```\n\n### remove()\n\nActs like `unset()`, but if the unset item is an element in a nested array, the array will be compacted.  For example:\n\n```javascript\nuser.get('addresses').length; //=\u003e 2\nuser.remove('addresses[0]');\nuser.get('addresses').length; //=\u003e 1\n```\n\n## See also\n\nNote, this plugin does *not* handle non-embedded relations (a.k.a. relations), which keeps it relatively simple.  If you support for more complex relationships between models, see [the Backbone plugin wiki page](https://github.com/jashkenas/backbone/wiki/Extensions,-Plugins,-Resources#relations). There is also an open discussion about [merging this project with backbone-deep-model](https://github.com/powmedia/backbone-deep-model/issues/14).\n\n## Contributing\n\nPull requests are more than welcome - please add tests, which can be run by opening test/index.html.  They can also be run from the command-line (requires [PhantomJS](http://phantomjs.org/)):\n\n    $ npm install\n    $ grunt\n\nSee also: [live tests](http://afeld.github.com/backbone-nested/test/) for latest release.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafeld%2Fbackbone-nested","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fafeld%2Fbackbone-nested","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafeld%2Fbackbone-nested/lists"}