{"action":"closed","issue":{"url":"https://api.github.com/repos/knockout/knockout/issues/794","labels_url":"https://api.github.com/repos/knockout/knockout/issues/794/labels{/name}","comments_url":"https://api.github.com/repos/knockout/knockout/issues/794/comments","events_url":"https://api.github.com/repos/knockout/knockout/issues/794/events","html_url":"https://github.com/knockout/knockout/issues/794","id":9879255,"number":794,"title":"Improve support for components (Feature Request / Proposal)","user":{"login":"ghost","id":10137,"avatar_url":"https://avatars.githubusercontent.com/u/10137?v=3","gravatar_id":"","url":"https://api.github.com/users/ghost","html_url":"https://github.com/ghost","followers_url":"https://api.github.com/users/ghost/followers","following_url":"https://api.github.com/users/ghost/following{/other_user}","gists_url":"https://api.github.com/users/ghost/gists{/gist_id}","starred_url":"https://api.github.com/users/ghost/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ghost/subscriptions","organizations_url":"https://api.github.com/users/ghost/orgs","repos_url":"https://api.github.com/users/ghost/repos","events_url":"https://api.github.com/users/ghost/events{/privacy}","received_events_url":"https://api.github.com/users/ghost/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2013-01-11T13:03:56Z","updated_at":"2015-04-07T13:33:37Z","closed_at":"2015-04-07T13:33:37Z","body":"Currently, if you want to create a reusable UI component with KnockoutJS, you need at least 2 things:\r\n\r\n1. manually create the stopBinding handler and add to the root of the component - This is required because we don't know where the component will be used and if it is inside another model. The stopBinding is required because if the markup is there when the page is loaded, it will throw errors about binding things it shouldn't know about.\r\n\r\n2. replace all the \"with\" with \"template : { if: ... data: ... afterRender: ... }\" - This is necessary because if you bind events to anything inside your component (and if it is a component, you will have them), you don't know when the nodes will be removed by another parent viewmodel.\r\n\r\nThose are completely doable in the current versions, but require us having to deal with issues that don't need to be there in the first place, and add time to developement and complexity to the code. There are some simple additions that could really help.\r\n\r\nHere are my proposals:\r\n\r\n1. Include \"stopBinding\" in the official package or similar functionality - this should be core functionality and not a custom binding. We really need to be able to add something to the page and don't worry if a parent model will try to bind to it. I would go with something like \"context: root/new/empty\" instead of \"stopBinding: true\", as it would make more sense when reading root markup of a component\r\n\r\n2. Add new \"if/with\" binding handlers or an option to the current ones that instead of removing the elements, will just apply \"display: none\", and when in that state, will use the \"stopBinding\" functionality to avoid binding to its children. Maybe something like \"with: someObject, removeChldren: false\". This would solve 90% of our constantly rebinding of events to elements that don't need to be removed from screen.\r\n\r\n3. Make \"afterRender\" available for any bindingHandler that causes elements to be re-rendered (like if/with), as sometimes we won't have the option to just hide them."}}