-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request feature: runtime composition of ko 3.2 component #1463
Conversation
This is similar to what I was asking for in #1458 but this is a better example of why it's a good idea. I think it could be easily implemented by allowing the component custom binding to apply its viewModel to its descendants like a normal custom binding when no template is defined by the component. Of course you could accomplish it with a custom binding for ko-toolbar but it sticks out like a sore thumb that you can't make use of the syntactic sugar of custom elements, especially when it's just a custom binding underneath. You could also accomplish it by supplying the buttons as a parameter to ko-toolbar, but that lacks flexibility. There are definite use cases where it feels natural to treat the the inner html of the custom element as the template of the component. |
I have a different view, to take advantage of runtime composition, the logic of container and child should be totally decoupled. The child could bind to something that the container has no visibility on.
ko could parse all container and children components independently, and the container only need to provide a placeholder in DOM for ko to inject the children. This also means ko doesn't care whether the children are components or DOM tags or mixed. Sure, we want communication between child and the container, that can be achieved with special binding context like
|
Yep, agreed - there's definitely a good use case here and I'm sure it will fit into the components system. We can try to formalise this into a plan after 3.2.0 ships. |
I could definitely use this...another vote in favor. |
+1 |
1 similar comment
+1 |
+1 |
+:8ball: |
+1, it will simplify components sharing between apps |
+1 |
1 similar comment
👍 |
+1 Also referencing #1493. Would provide a clean way to programmers to configure presentation logic in a much cleaner and natural way. |
This is very important for me. In my case, I need to be able to dynamically construct the viewmodel and then a template for a viewmodel. This is for creating forms with input fields where those inputs fields can vary based on the data type of the properties for the viewmodels (so I can construct an input field that has a custom binding handler to load a jQuery datepicker, etc.). There is an assumption that templates and viewmodels are independent and that templates can be loaded before the viewmodel is instantiated. But the templates used do not exist. There is a builder that looks at the viewmodel properties and creates the markup based on conditions defined within the builder of the template. Referencing #1458 that has more details about the issues and the limitations encountered. I had a solution working (building a viewmodel and template dynamically) with version 3.1, but the solution was incomplete because I could not re-apply bindings to the container element with an updated viewmodel, or remove the existing binding and apply a new one to the container element. |
+1 |
+1 |
After looking into Durandal's implementation, mentioned in #1493, I tried to figure out how the components system can be extended to allow for similar functionality, as sort of an exercise as I'm learning my way around Knockout. I've created a new binding based on the code of the componentBinding which allows defining overridable parts of a component. Here is a quick example: http://jsfiddle.net/mbaranov/6zvjfd2y/. It shows an implementation of a simple expander control with the overridable header and content parts. The composableComponent binding implementation is a word-by-word copy of the component binding with bits of the new code, that I maked with the comments. |
When injecting supplied nodes into a component output, it’s useful to be able to pass the node array directly from the component viewmodel and bind to those nodes in the view. If we didn’t have this feature, you’d have to dynamically create a named template or something, which would be awful.
…pt inline templates
OK, implemented. This is a reasonably simple change and hopefully provides a very valuable enhancement. This implementation is slightly more low-level than @mbaranov's, in that it just supplies the inner nodes to |
I think that it would be nice if the inner nodes were also provided in a context variable ($componentTemplate or nodes or something like that) for easy binding, so in normal cases the view model wouldn't need to reference them. |
Request feature: runtime composition of ko 3.2 component
Good idea! Done. It's called |
Going further into this discussion, I've reworked a bit the latest available source for the component binding to also support the so called insertion points: imagine we want a bootstrap-panel component that wraps its content into a bootstrap panel. We would like to write our component as <bootstrap-panel>
<header>
My panel
</header>
<main>
<strong>My content</strong>
</main>
<footer>
My footer
</footer>
</bootstrap-panel> Then, our template could look like: <div class="panel panel-default">
<div class="panel-heading">
<content select="header" />
</div>
<div class="panel-body">
<content select="main" />
</div>
<div class="panel-footer">
<content select="footer" />
</div>
</div> The key feature here is the The final output, then, will be: <bootstrap-panel>
<div class="panel panel-default">
<div class="panel-heading">
<header>
My panel
</header>
</div>
<div class="panel-body">
<main>
<strong>My content</strong>
</main>
</div>
<div class="panel-footer">
<footer>
My footer
</footer>
</div>
</div>
</bootstrap-panel> I really hope this approach can prove to be useful. At present time, though, I needed to edit the component binding source, since there's no pluggable way the edit it easliy, so if any of you are interested, I can probably build a PR and make it available. |
@unsafecode, that is very similar to what was suggested in #1493 however I like your syntax better. |
This also takes care of #1493
|
@austinhyde That looks pretty nice. |
Right now, ko 3.2 component supports composition directly in component's template. This kind of composition only happens in definition time.
Would suggest to support runtime composition, so we can define kind of "container" component, and make tags more expressive.
The usage is something like this:
FYI, this feature is available on Google Polymer through
<content>
tag,