We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.
Allen Rice you can install it via bower using: bower install knockout#3.2.0-alpha or get the files directly from: https://github.com/knockout...
Thanks Ryan! I'm currently messing with the project and builds in order to get this compiling and running via TFS / Visual Studio (with TypeScript). I'll put up a post when I'm done and link back
Ryan is it too late to include support for transclusion? I feel without it, these custom components will be little more than syntactic sugar over the template binding, with some support for widget loading/require which could be done with a pretty straight-forward rewrite of a templating engine.
Also, I hope this comment doesn't come across as too negative or anything. I'm really glad to see that you guys are willing to expand the API to fit some emerging trends such as web components, etc. I just want to see it succeed!
I would also be happy to help out in this regard, I believe you've already seen some of my approach for building in compents for knockout: https://github.com/lelandri...
Leland, it looks like these components give you very fine grain control over the loading process, so you'd be able to put transclusion in there pretty easily. I think they give you a callback, so you'd just do all the plumbing to copy the template once and store it for duplication. It shouldn't be too hard, although I may be mistaken, because this is the first time I've heard the term and I had to figure out what it meant via your url :)
Allen Rice, thanks for looking into it (indeed, I hate the term "transclusion" as well... ), but I don't think this provides an easy way to do it. Another term for it would be to include "insertion points", which is what the web components spec calls it.
http://www.w3.org/TR/compon...
This, in my mind, is really the magic of web components. Without it, components are more or less just a reusable set of templates + logic. With insertion points it is much easier to imagine complex and generic UI widgets being built as "components".
Leland Richardson - For 3.2, we are focusing on getting the basic functionality and extensibility points in place in the core, so all KO users can feel some benefits from day one. In my opinion, as the other plugins mentioned have shown, there is more to it than a "straight-forward rewrite of a templating engine", which is far from straight-forward to someone just picking up KO. There will certainly be room to consider and include additional features or extensibility points in the future. Definitely a good idea!
While we wait for official support for insertion points, is there some way one could hack in some partial support.
Particularly I'm thinking of things like dialog boxes -- letting my <my-dialog> element define the borders and background and such, while rendering whatever is in between <my-dialog>...</my-dialog> inside the box.
Is there, for example, some place one could hook in a callback that gives you access to the innerHTML of a custom component, before the component's template is asked for? That would give you a chance to modify the template from instance to instance, injecting the innerHTML into it. Or have I got it all backwards?
I have attempted to try to this with the current beta release but as mentioned there is no hook for when a component has rendered it's template. Putting a custom binding on the template is no good as there is no clean way to map an element from a rendered template to its parent component element.
Would really be nice to have a hook for this. Only way I can get this done now is by wrapping `applyBindingsToDescendants`, which doesn't work in the non debug build.
pbouzakis - I was going to suggest applyBindingsToDescendants, if you want to first render the children before executing code on the parent. It is available in the minified build. Can you describe/demonstrate the issue that you had in the non-debug build?
Hey Ryan Niemeyer, thanks for the quick reply.
`applyBindingsToDescendants` is made public via `exportSymbol`, but because the method is not quoted, inside ko, it references the minified symbol and therefore my wrapper is never called.
In debug, my plugin for insertion points / transclusion works like a charm for custom elements, and elements (including virtual) wrapping `applyBindingsToDescendants`.
I guess that I misunderstood what you were trying to do. I didn't realize that you were trying to monkey-patch that method. Can you share some code with me?
Yeah I rather not monkey patch, but until we have the hooks don't think I have any other options.
https://gist.github.com/pbo...
So I was attempting to have most of my plugin do it's work inside the `preprocessNode` hook. So all I do in `applyBindingsToDescendants` is check if the element has nodes we want to insert on binding, if so, call my private function to do the work.
This sounds pretty solid. One thing I'm not seeing here is the ability to load multiple templates per view model. We've built a custom binding which loads a set of templates asynchronously. Based on the view model's state (e.g. viewModel.isEditState()), the binding renders one of the templates. I realize we could just load one template with a series of conditions (). However, those condition elements would end up in the DOM. That would bloat the DOM unnecessarily, particularly in data grids.
I like the idea, I guess it will influence the Web components spec if it gets popular?
What is the intention going forward, will this be kept up-to-date with the Web components spec (like TS adjusting to ES6 spec) so we can be save that the migration to web components will be relatively painless in 2 years, or is this not a declared goal?
Hi Ryan, thanks for the nice introduction. Really helps to see the different possibilities. I'm trying to build on the sample custom loader, but I'm having a problem with an error. I get: Uncaught Error: Component 'view-home': Unknown viewModel value: [object Object]. Where view- is the prefix I choose and in the config to viewModel I strip "view-" and send value home.
SatheesA - are you still having this issue? can you share some additional code?
Hi Ryan! Awesome stuff! I did not see knockout.js go in that direction, but I am really glad you did find a super way of integrating components into knockout.
Can't wait to see first examples with it!
You rock!
Regards
Andreas
Is it possible to compose components ? Could one component use another component in its template ?
Randoom - Yes for sure. Components can freely use other components in their template. That should open up a lot of interesting possibilities.
Nice article! Is somewhere any working demo with components loaded via require? Thanks for reply.
When does this come out? I need this now for a large enterprise system?! lol. Are there alpha bits that I can pull down today?
Nevermind. I got too excited. I'll head over to the GitHub today!
Can you link to css files from templates? If so, how?
@Anders - you can render a <link> element inside of a template and it will be applied (to the entire page) while the element is there.
Ryan, is it possible to create a web component like XAML grid? It'll manage the laying out of other web components that it contains? Any similar sample for inspiration?
Thanks and regards
How does the lifetime of the component get managed from the viewModel? What I mean is - if you look for example at Durandal, they have a predefined list of lifetime actions that happen when a page/widget gets loaded/rendered etc. and you have the option to intercept these steps and perform various operations.
This also allows you to do two important things:
1. Postpone the activation of the view model until the promise that gets returned in each of these steps gets resolved (for example perform initialization before any HTML gets rendered).
2. Know exactly when the HTML is available in the DOM so that you can do direct manipulation on it (not nice, but many times necessary).
It would be really cool if the components would support such activation/lifetime events.
Yes! Sebastian Negomireanu , I have the same question. Ryan Niemeyer , it would be great to know if you guys have thought about at least basic support. My use case is:
I have a component that gets data and will render a graph. I want to do that once I know my template has been rendered (with the graph placeholder). And $(document).ready doesn't quite work because this component could be rendered after the initial page. So in the most basic case, I think I'd need:
MyViewModel.prototype.render = function(element){
graphingComponent.render(this.definition, element);
}
Sebastian NegomireanuDan Andreescu there was some discussion about life cycle events, specifically around things like animating in/out a component. In 3.2, there is nothing specific in place other than that if you use a createViewModel function you have access to the element prior to it being rendered. Additionally, we do look for a "dispose" function for when the component is removed. For functionality, after it has been rendered, a custom binding on the top-level element has been my preference over afterRender functions on the template binding. This gives you good control-over where/how it fires. I think in future versions, there is definitely a possibility that additional life-cycle hooks will be included.
Thanks very much Ryan. Custom binding it is, and we look forward to future versions.
We've only just started using the beta release of this feature, but have to say: it's simply AWESOME! So glad this is being added to the core.
Question: will ko custom elements support Web Component-style attribute definitions or must all attrs be defined via `params`?
<my-component params="name: first() + ' ' + last()"></my-component>
vs:
<my-component name="first() + ' ' + last()"></my-component>
or even better:
<my-component name="{{ first }} {{ last }}"></my-component>
mshwery in 3.2, it will only support params. In the future, we are definitely considering support for it. The design (https://github.com/knockout... has information about the type of syntax that you are suggesting. Definitely makes sense as a nice way to define a component.
Interesting. It definitely makes sense that the `params` definition is virtually no different than parsing the `data-bind` value, so it seems logical for that to be the first-supported syntax.
Although I still prefer the latter syntax with individual attribute definition, or handlebars-style syntax.
Hi Ryan
In ViewModel of Components we need the callback function for telling that the template has been attached to html.
Because in my case I need to call $(element).trigger("create"); with jquery mobiles theme
need a call back function attachComplete: function (element) {
$(element).trigger("create");
}
As Ryan suggested: do it with data-bind on the template of the created element.
In my case I have a custom ko.bindingHandlers.init that does this for me.
Is it or will it be possible to nest components?
I may not "think correctly" but how could I say that I want a custom component to be a child of another custom component? Is that possible? I guess not because we supply the template and there's no "wrapping" option.
For example, a <panel> (that has params like src, data) would go into a <panel-group> for example. And then programmatically switch the <panel-group> of one panel with knockout.
Not sure if I'm mistaking, but for the moment I would have to manage the parent with jQuery and <panel> with a knockout component.
Ryan wrote: "Components can freely use other components in their template. That should open up a lot of interesting possibilities."
Except that components are using templates to render themselves, so any content inside a component is getting destroyed. That's why I asked that question. If a component as a string template refering other components it's OK, but if a component has already components set inside HTML DOM, it's getting destroyed and replaced by its template, which makes us unable to use components within components.
That would be good to have a special string within the template that would say "put every already existing node in that place".
I very much agree with this. Without being able to nest components it's pretty difficult to create general components. For example how could you create a tab component? You'd want to be able to put elements inside a tab, but once the tab component gets instantiated it's going to blow away all the elements inside.
@sd Micaël Félix @michael - We will certainly be looking at ways to work with the child elements of a component in the next release (after 3.2). For now, your best bet is to allow the component to pass in the name of templates to use inside. For example, a tab component could allow you to pass in an array of tab config objects that have like a name, and contentTemplateName properties.
Do you think it would be possible to use the custom loadComponent so it returns a set of already existing children nodes in the current version of knockout?
The idea would be to get the base node of the component (before the template is executed/appended) to read its children and then later copy them somewhere in the array of nodes that are created from the template of that component? Theoritically that would work, wouldn't it?
What is the progress update on the 3.2 update?
John Farrar - we are finalizing the documentation and preparing for the release. I would expect 3.2 to be out in the next few days.
So in 3.2, how can I have my vm's talk to each other? Besides using an event system, we have found it useful to inject vm's into each other.
For example, an AppVM might want to hold a reference to the current page. Which is stored as a reference to another vm. You might even want to create your view model first, before you have rendered the template. A vm first approach does not seem possible without really tinkering with the library.
Would also like to see more than just dispose in terms of lifecycle events. I know I can create a custom binding, but I see these events as useful for app plugins. Would like there to be an easier way then putting some afterRender binding on every one of my components.
Hi Ryan,
I just wanted to let you know I'm working on a large SPA using knockout components and this blog post informed me of the dispose method. It pretty much saved my life. Thanks!
Ryan Whitmire - good to hear! Disposal / clean-up is very important in SPA development.
Excuse my stupid question as I may not be fully aware, will the ko.components binding support the before and after render events, for carrying out CSS3 transitions perhaps, maybe it supports this already and I am just unaware ?
Shay Doherty - The before/after render events are not specifically supported by components. I think that we will be looking at adding some additional events around components in the next version (no specific plan yet). It is possible to use templates (template binding) inside of your component with after/before render callbacks.
http://stackoverflow.com/qu... can you lease answer this
We're beginning a large SPA project with Knockout and TypeScript and we'd love to use this component functionality. Is there any way to use it in its current alpha state?
Great job so far, cant wait to see the final release!