{"id":20617071,"url":"https://github.com/kjantzer/backbone-subviews","last_synced_at":"2025-10-07T07:25:49.334Z","repository":{"id":22686243,"uuid":"26029971","full_name":"kjantzer/backbone-subviews","owner":"kjantzer","description":"Extends Backbone.View with support for nested subviews that can be reused and cleaned up when need be.","archived":false,"fork":false,"pushed_at":"2018-09-18T21:07:34.000Z","size":18,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-17T21:44:12.821Z","etag":null,"topics":["backbone","backbone-subviews","backbonejs","javascript","nested-subviews","subviews"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kjantzer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-31T19:18:16.000Z","updated_at":"2023-03-08T04:37:38.000Z","dependencies_parsed_at":"2022-08-17T16:30:36.193Z","dependency_job_id":null,"html_url":"https://github.com/kjantzer/backbone-subviews","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kjantzer%2Fbackbone-subviews","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kjantzer%2Fbackbone-subviews/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kjantzer%2Fbackbone-subviews/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kjantzer%2Fbackbone-subviews/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kjantzer","download_url":"https://codeload.github.com/kjantzer/backbone-subviews/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242269713,"owners_count":20100158,"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-subviews","backbonejs","javascript","nested-subviews","subviews"],"created_at":"2024-11-16T11:22:03.153Z","updated_at":"2025-10-07T07:25:44.288Z","avatar_url":"https://github.com/kjantzer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Backbone.js Subviews\n===================\n\n![Version 0.7.0](https://img.shields.io/badge/Version-0.7.0-blue.svg)\n\n\u003eExtends `Backbone.View` with support for nested subviews that can be reused and cleaned up when need be. (helps mitigate ghosted views)\n\n## Features\n\n- Cleanup views when no longer needed\n- Provided access to parent views\n- Add additional methods to help with reusing Views\n- Keeps views uninitialized until needed\n- Propagates `model` to subviews\n- Listen to models/collections by defining them in a hash\n- And more...\n\n## Using Subviews\n\n```javascript\nvar MySubview = Backbone.View.extend({\n\t\n\trender: function(){\n\t\tconsole.log(this.parentView.className) // 'my-view'\n\t\tconsole.log(this.viewName) // 'my-subview'\n\t},\n\t\n\tcleanup: function(){\n\t\tconsole.log('perform cleanup')\n\t\t// such as this.stopListening(this.model)\n\t}\n});\n\nvar MyView = Backbone.View.extend({\n\t\n\tclassName: 'my-view',\n\t \n\tinitialize: function(){\n\t\tthis.sv('my-subview', MySubview).renderTo(this)\n\t},\n\t\n\trender: function(){\n\t\n\t\t// render the child view\n\t\tthis.sv('my-subview').render();\n\t\n\t\treturn this;\n\t}\n})\n```\n\nWhen you remove a view, all subviews will be informed and told to cleanup\n\n```javascript\nMyView.remove() // MySubview:'perform cleanup'\n```\n\nYou can reuse views too instead of recreating over and over.\n\n```javascript\nvar MyListSubivew = Backbone.View.extend({});\n\nvar MyListView = Backbone.View.extend({\n\t\n\trender: function(){\n\t\n\t\tthis.$el.html('')\n\t\t// assuming this view has a collection...\n\t\tthis.collection.each(this.addOne, this)\n\t\n\t\treturn this;\n\t},\n\t\n\taddOne: function(model){\n\t\t\n\t\tlet viewName = 'item-'+model.id\n\t\t\n\t\t// MyListSubivew will only be initialized once for the given viewName\n\t\tthis.sv(viewName, MyListSubivew)\n\t\t\t.setModel(model)\n\t\t\t.renderTo(this)\n\t\t\n\t\t// if you data/options are needed upon initialization of the view, you can do This\n\t\t// this.sv(viewName, MyListSubivew, {model: model, another:'option'})\n\t}\n})\n```\n\n## Defining Views\n\nSince creating and appending subviews to a view is a common routine, backbone.subviews provides a way to setup and render them automatically for you.\n\n```js\nvar View1 = Backbone.View.extend({className: 'v1'});\nvar View2 = Backbone.View.extend({className: 'v2'});\nvar BadgeView = Backbone.View.extend({className: 'badge'});\nvar ViewColl = Backbone.View.extend({className: 'v-coll', tagName: 'ul'});\n\nvar RootView = Backbone.View.extend({\n\n\tclassName: 'rootview',\n\ttemplate: '\u003ch1 class=\"title\"\u003eTitle\u003c/h1\u003e',\n\n\tviews: {\n\t\t'view1': View1,\n\t\t'view2': View2,\n\t\t'badge': {\n\t\t\tview: BadgeView,\n\t\t\tappendTo: '.title'\n\t\t},\n\t\t'view-collection': {\n\t\t\tview: ViewColl,\n\t\t\tsetModel: function(v, model){\n\t\t\t\tv.collection = model.get('a-child-collection')\n\t\t\t}\n\t\t}\n\t}\n\n});\n```\n\nWhen the RootView is rendered, all the views defined in `views` will be initialized, appended to RootView and then their `render()` method called.\n\n**This will give us the following DOM structure**\n\n```html\n\u003cdiv class=\"rootview\"\u003e\n\t\u003ch1 class=\"title\"\u003eTitle\u003cdiv class=\"badge\"\u003e\u003c/div\u003e\u003c/h1\u003e\n\t\u003cdiv class=\"v1\"\u003e\u003c/div\u003e\n\t\u003cdiv class=\"v2\"\u003e\u003c/div\u003e\n\t\u003cul class=\"v-coll\"\u003e\u003c/ul\u003e\n\u003c/div\u003e\n```\n\n\u003e If you override `render` you'll need to remember to call `renderViews()` on your own.\n\n## Attaching Listeners to Model/Collections\n\nIt is common practice for a view to listen to a model or collection for changes and react accordingly. This can be done by specifying a hash of events like so:\n\n```js\nlisteners: {\n\tmodel: {\n\t\t'change': 'render',\n\t\t'destroy': 'remove',\n\t\t'reset': function(){\n\t\t\t// inline function also supported\n\t\t}\n\t},\n\tcollection: {},\n\t'name-of-child-collection': {}\n}\n\n// the above is the equivalent of doing this manually\nthis.listenTo(this.model, 'change', this.render)\nthis.listenTo(this.model, 'destroy', this.remove)\nthis.listenTo(this.model, 'rest', function(){})\n```\n\nYou'll notice above that [Child Collection](https://www.npmjs.com/package/kjantzer-backbone-child-collections) is supported. The third listener would evaluate to:\n\n```\nthis.model.get('name-of-child-collection')\n```\n\n## Methods \u0026 References\n\nThere are some useful methods added to Backbone.Views\n\n`.sv()` or `.subview()` - save and access subviews\n\n`.renderTo()` - render and append to a backbone view (or jquery element)\n\n`.empty()` - clears the view of contents\n\n`.inDOM()` - whether or not the view is presented in the DOM or just stored in memory\n\n`.reRender()` - will only render if in the DOM\n\n`.renderViews()` - init and append (if needed) and then render all defined views (`this.views`)\n\n`.forEachView(callback)` - perform an action on all defined `views`\n\n`.renderTemplate()` - will take `this.template` and merge with `this.model` and append to el. (See [backbone.template-data](https://github.com/kjantzer/backbone-template-data))\n\n`.parentView` - a reference to the parent view of this child\n\n`.parent(viewName, returnPromise=false)` - will traverse up parent views until matched view name. Use `root` to get the top level view. Dot notation is supported for traversing up to a parent and then down to a subview.\n\n`.viewName` - the name the child is stored under in the parent\n\n\n## Changelog\n\n#### v0.7.0\n- Defined `views:{}` will get `setModel` called upon initialization (if they have it)\n- Model/Collection listeners can be defined and applied automatically\n\n#### v0.6.2\n- `collection: this.collection` also passed to view upon creation (previously only this.model was given)\n\n#### v0.6.1\n- fix `.sv` alias not passing `opts` arg\n\n#### v0.6.0\n- return `this` in `setModel` for chainability\n- add `renderTo` method\n- `view` arg in `.sv()` can be uninitialized - the view will only initialize once.\n- defined view in `views` has `setModel` option available\n\n#### v0.5.0\n- new `.parent(viewName, returnPromise=false)` method for traversing up the parent views to the one matching the given name\n\n#### v0.4.0\n- add support for defining and automating subviews on a view\n\n## License\n\nMIT © [Kevin Jantzer](https://twitter.com/kjantzer) - [Blackstone Publishing](http://www.blackstonepublishing.com/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkjantzer%2Fbackbone-subviews","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkjantzer%2Fbackbone-subviews","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkjantzer%2Fbackbone-subviews/lists"}