{"action":"created","issue":{"url":"https://api.github.com/repos/mikeric/rivets/issues/553","repository_url":"https://api.github.com/repos/mikeric/rivets","labels_url":"https://api.github.com/repos/mikeric/rivets/issues/553/labels{/name}","comments_url":"https://api.github.com/repos/mikeric/rivets/issues/553/comments","events_url":"https://api.github.com/repos/mikeric/rivets/issues/553/events","html_url":"https://github.com/mikeric/rivets/issues/553","id":129782250,"number":553,"title":"Components enhancements","user":{"login":"stalniy","id":1159966,"avatar_url":"https://avatars.githubusercontent.com/u/1159966?v=3","gravatar_id":"","url":"https://api.github.com/users/stalniy","html_url":"https://github.com/stalniy","followers_url":"https://api.github.com/users/stalniy/followers","following_url":"https://api.github.com/users/stalniy/following{/other_user}","gists_url":"https://api.github.com/users/stalniy/gists{/gist_id}","starred_url":"https://api.github.com/users/stalniy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stalniy/subscriptions","organizations_url":"https://api.github.com/users/stalniy/orgs","repos_url":"https://api.github.com/users/stalniy/repos","events_url":"https://api.github.com/users/stalniy/events{/privacy}","received_events_url":"https://api.github.com/users/stalniy/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2016-01-29T14:34:28Z","updated_at":"2016-02-13T00:28:47Z","closed_at":null,"body":"Currently components lacks really powerful features:\r\n1. Lifecycle. There is only 2 methods `initialize` and `template` and last one is called first then first one. That means that developer can decide which template to render based on input information from the attributes. For example, I'd like to have a component which is something similar to `input` tags with different types but more complex, e.g. `datepicker`, `autocomplete`, etc. So, that I do this in HTML:\r\n```html\r\n<form-field type=\"datepicker\" value=\"birthDate\"></form-field>\r\n```\r\nAnd my component is this:\r\n```js\r\nrivets.component['form-field'] = {\r\n  initialize: function(el, attrs) {\r\n    return new FormField(attrs);\r\n  },\r\n\r\n  template: function(scope) {\r\n    return TEMPLATES.get(scope.type);\r\n  }\r\n};\r\n```\r\nCurrently it's not possible. The only possible solution is to create separate component for each `form-field`. But logically it should be one component with extendable points and some shared behaviour\r\n2. `initialize` accepts 2 arguments: object of attributes and `HtmlElement` and this allows devs to write worse code as it mixes concepts (view - element, parsed attrs - kind of model). Another reason why it should be split into 2 because view (rivets binders) assigns view related variables (i.e. `rv-each-*`) right into my component controller what can lead to names collisions and unpredictable behaviour. So, something like `{ [componentName]: component.initialize() }` should be view scope and not just `component.initialize()` result.\r\n3. Sometimes you have a component with its default template but then you want to use it in another place with a bit different template. Currently there is no way to change components parts. This is what `transclusion` cares about. So, it allows to define parts inside components which can be overridden if necessary. So, you can do like this:\r\n```html\r\n<form-field type=\"number\">\r\n  <label>My custom label</label>\r\n  <div rv-part=\"error\">My custom error message</div>\r\n</form-field>\r\n```\r\nAnd Components template:\r\n```html\r\n<div class=\"form-group\">\r\n   <label class=\"control-label\" rv-transclude=\"label\">{ label }</label>\r\n   <input type=\"number\" rv-value=\"value\" class=\"form-control\">\r\n   <div rv-transclude=\"error\" class=\"help-block error\">{ error }</div>\r\n</div>\r\n```\r\nIn this example `form-field` will replace `part` which is called `label` inside default template with the provided tag. \r\n4. Components doesn't not allow to return document fragment from their template. In the same time document fragment is the most performant way to put a bunch of HTML in DOM tree.\r\n5. Sometimes you want to specify component's template as a string (when there is no need in function, you just have prepared HTML or want to put it right there without writing extra function)\r\n```js\r\nrivets.components.tabset = {\r\n  template: `\r\n    <ul class=\"tabs\">\r\n      <li rv-each-tab=\"tabs\" rv-click=\"selectTab\">{ tab.title }</li>\r\n    </ul>\r\n    <div rv-transclude></div>\r\n  `,\r\n\r\n  initialize: ....\r\n};\r\n```\r\nHere no need in function, so more convenient to pass just a string.\r\n6. No support for dependent components like `tabset` and `tab`. For example currently this is not possible as components just remove inner html\r\n```html\r\n<tabset>\r\n  <tab title=\"Overview\">Tab Content</tab>\r\n  <tab title=\"Settings\">Settings</tab>\r\n</tabset>\r\n```\r\nAlso it's not possible to access parent component inside child one at the moment.\r\n\r\n\r\n@blikblum, @Leeds-eBooks, @jccazeaux want to hear your thoughts about this as I have already done all this (and a bit more in my fork). So, if we are ok with that we could split these tasks to smaller one and I will create a separate pull-request for each."},"comment":{"url":"https://api.github.com/repos/mikeric/rivets/issues/comments/183541312","html_url":"https://github.com/mikeric/rivets/issues/553#issuecomment-183541312","issue_url":"https://api.github.com/repos/mikeric/rivets/issues/553","id":183541312,"user":{"login":"jccazeaux","id":5689583,"avatar_url":"https://avatars.githubusercontent.com/u/5689583?v=3","gravatar_id":"","url":"https://api.github.com/users/jccazeaux","html_url":"https://github.com/jccazeaux","followers_url":"https://api.github.com/users/jccazeaux/followers","following_url":"https://api.github.com/users/jccazeaux/following{/other_user}","gists_url":"https://api.github.com/users/jccazeaux/gists{/gist_id}","starred_url":"https://api.github.com/users/jccazeaux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jccazeaux/subscriptions","organizations_url":"https://api.github.com/users/jccazeaux/orgs","repos_url":"https://api.github.com/users/jccazeaux/repos","events_url":"https://api.github.com/users/jccazeaux/events{/privacy}","received_events_url":"https://api.github.com/users/jccazeaux/received_events","type":"User","site_admin":false},"created_at":"2016-02-13T00:28:47Z","updated_at":"2016-02-13T00:28:47Z","body":"I have a question about transclusion:\r\n```html\r\n<form-field type=\"number\">\r\n  <label>My custom label</label>\r\n  <div rv-part=\"error\">My custom error message</div>\r\n</form-field>\r\n```\r\nWhat will be `rv-part`? It looks like a binder but its value is more like an alias than an `expression`."}}