{"id":20525983,"url":"https://github.com/codeyellowbv/backbone-crux","last_synced_at":"2025-10-17T18:49:12.576Z","repository":{"id":66356449,"uuid":"61743556","full_name":"CodeYellowBV/backbone-crux","owner":"CodeYellowBV","description":"A set of opinionated additions to Backbone ","archived":false,"fork":false,"pushed_at":"2017-01-29T16:43:28.000Z","size":148,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-01-16T11:26:54.799Z","etag":null,"topics":[],"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/CodeYellowBV.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-22T18:49:52.000Z","updated_at":"2016-10-27T08:51:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"de981c00-1cd7-4699-bb30-c9e610bf949d","html_url":"https://github.com/CodeYellowBV/backbone-crux","commit_stats":{"total_commits":145,"total_committers":5,"mean_commits":29.0,"dds":0.6827586206896552,"last_synced_commit":"bdddfbff5443e616c9accd5034951254718321b3"},"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeYellowBV%2Fbackbone-crux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeYellowBV%2Fbackbone-crux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeYellowBV%2Fbackbone-crux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeYellowBV%2Fbackbone-crux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CodeYellowBV","download_url":"https://codeload.github.com/CodeYellowBV/backbone-crux/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242133331,"owners_count":20077095,"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":[],"created_at":"2024-11-15T23:11:42.113Z","updated_at":"2025-10-17T18:49:12.453Z","avatar_url":"https://github.com/CodeYellowBV.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# backbone-crux\n\n[![Build Status](https://travis-ci.org/CodeYellowBV/backbone-crux.svg?branch=master)](https://travis-ci.org/CodeYellowBV/backbone-crux)\n\nAn opinionated library with simple, but unmissable additions to Backbone, Backbone.Paginator, backbone.stickit and Marionette.\n\nAt Code Yellow, we’ve been relying on these additions for over two years.\n\n```\n$ npm install backbone-crux --save\n```\n\n## Usage\n\n### Model\n\nThis section describes what functionality is added to the `Backbone.Model`.\n\n#### parse {ignore: true || ['keys', 'to', 'be', 'ignored']}\n\nExtended parse to add a new feature: ignore. If `options.ignore = true`, the parse function returns an empty object and effectively ignores the server response. This can be useful when you use patch where you simply want to set an attribute and not let the server result influence other attributes. If you supply an array, those keys will be omitted from the response before parsing.\n\n#### isEmpty\n\n`isEmpty` checks whether a model is still in the original, default, state, and thuss practically empty. An example:\n\n```js\nimport { Model } from 'backbone-crux';\n\nconst Bar = Model.extend({\n    defaults() {\n        return {\n            id: null,\n            type: 'foo',\n        }\n    }\n});\n\nconst bar = new Bar();\nbar.isEmpty(); // true\nbar.set('type', 'bar');\nbar.isEmpty(); // false\n```\n\n#### toJSON\n\n`toJSON` is modified to recursively flatten everything. This means that if you nest a model in a model, and then call `model.save()`, `toJSON` is also called for the nested model.\n\n#### toHuman\n\n`toHuman` will recursively flatten everything, like `toJSON`. `Marionette.View` automatically uses `toHuman` and adds it to your template.\n\n#### fromHuman\n\n`fromHuman` can be used in a view to parse data from a human readable format to a server readable format. By default it does the exact same as `set`, but you can override it in your model.\n\n### Collection\n\nThis section describes what functionality is added to the `Backbone.Collection`.\n\n#### Paginator\n\nThe collection is always extended from [backbone.paginator](https://github.com/backbone-paginator/backbone.paginator), and automatically parses API responses to fit into the collection.\n\nThe following format is expected from the API:\n\n```json\n{\n    \"data\": [{}, {}],\n    \"totalRecords\": 2,\n}\n```\n\n`totalRecords` should contain all records that were found (so not only the records that are in `data`!).\n\n#### attributes\n\nThe collection has a model, called `attributes` in it. This model represents the data that will be added to each request.\n\n```js\nimport { Collection } from 'backbone-crux';\n\nconst collection = new Collection(null, {\n    uri: 'api/example'\n    attributes: {\n        foo: 'bar',\n    },\n});\n\ncollection.fetch();\n```\n\nThis will result in a fetch to `api/example?foo=bar`. Because the attributes are a model, it is very easy to listen to state changes and e.g. update a filter.\n\nTo add an attribute, you can do: `collection.attributes.set('lorem', 'ipsum')`. All new fetches will then use `api/example?foo=bar\u0026lorem=ipsum`.\n\n#### fetchData\n\nBy default, a fetch is done with data from the `attributes` model. It is possible to override this, and enforce that only specific attributes are used:\n\n```js\nimport { Collection } from 'backbone-crux';\n\nexport default Collection.extend({\n    fetchData() {\n        return _.omit(this.attributes, 'foo');\n    },\n});\n```\n\n#### xhr\n\nA XHR request for a fetch will be stored in `collection.xhr`. This allows you to e.g. easily abort a request when a view gets destroyed.\n\n### Stickit UI bindings with Marionette\n\nMarionette has the nifty `@ui` syntax to refer to html elements, but stickit \ndoes not. With backbone-crux, the `@ui` syntax is automatically enabled for stickit bindings.\n\nExample:\n\n```js\nexport default Marionette.ItemView.extend({\n    ui: {\n        title: '._title',\n    },\n    onRender() {\n        this.stickit();\n    },\n    bindings: {\n        '@ui.title': 'title',\n    },\n});\n```\n\n### XHR events\n\nFor every XHR request a model or collection does, a couple of events will be fired. The name of these events has the method in it (`create`, `read`, `update`, or `delete`).\n\nThe event `before:\u003cmethod\u003e` is fired just before the XHR request takes place. After the XHR request, `after:\u003cmethod\u003e` will be fired. Depending on the outcome of the request, `after:\u003cmethod\u003e:success` and `after:\u003cmethod\u003e:error` will be fired.\n\nAn example of how you can use this:\n\n```js\nexport default Marionette.ItemView.extend({\n    modelEvents: {\n        'after:read:success': 'onAfterReadSuccess',\n    },\n    onAfterReadSuccess() {\n        console.log('Look ma, I’m done fetching!');\n    }\n});\n```\n\n### Marionette plugins\n\nUsing external plugins can be quite a pain with Marionette. The `onRender` method can get very messy fast. Also, forgetting to destroy plugins can lead to small memory leaks. Marionette plugins aims to fix these problems. An example:\n\n```js\nexport default Marionette.ItemView.extend({\n    ui: {\n        input: '._input',\n    },\n    plugins: {\n        mask: {\n            bind() {\n                this.ui.input.mask('9999-99');\n            },\n            unbind() {\n                this.ui.input.unmask();\n            },\n        },\n    },\n});\n```\n\n`bind` is called when rendering a view. `unbind` is called when a view gets destroyed.\n\nYou can also define plugins as a function:\n```js\nexport default Marionette.ItemView.extend({\n    ui: {\n        input: '._input',\n    },\n    plugins() {\n        return {\n            mask: {\n                bind() {\n                    this.ui.input.mask('9999-99');\n                },\n                unbind() {\n                    this.ui.input.unmask();\n                },\n            },\n        };\n    },\n});\n```\n\n## Development\n\nTo run the tests (and also lint the source files), run:\n\n```\nnpm test\n```\n\n## Legal\n\nDistributed under ISC license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodeyellowbv%2Fbackbone-crux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodeyellowbv%2Fbackbone-crux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodeyellowbv%2Fbackbone-crux/lists"}