We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Allen Rice • 12 years ago

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!

Ryan Niemeyer • 12 years ago

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...

Allen Rice • 12 years ago

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

Leland Richardson • 12 years ago

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...

Allen Rice • 12 years ago

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 :)

Leland Richardson • 12 years ago

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".

Ryan Niemeyer • 12 years ago

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!

zacharias • 11 years ago

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?

pbouzakis • 11 years ago

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.

Ryan Niemeyer • 11 years ago

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?

pbouzakis • 11 years ago

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`.

Ryan Niemeyer • 11 years ago

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?

pbouzakis • 11 years ago

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.

Ben Rogers • 12 years ago

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.

okh397 • 12 years ago

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?

SatheesA • 12 years ago

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.

Ryan Niemeyer • 12 years ago

SatheesA - are you still having this issue? can you share some additional code?

Andreas Kroll • 12 years ago

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

Randoom • 12 years ago

Is it possible to compose components ? Could one component use another component in its template ?

Ryan Niemeyer • 12 years ago

Randoom - Yes for sure. Components can freely use other components in their template. That should open up a lot of interesting possibilities.

Ondřej Ždych • 12 years ago

Nice article! Is somewhere any working demo with components loaded via require? Thanks for reply.

Zias Zias • 12 years ago

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?

Zias Zias • 12 years ago

Nevermind. I got too excited. I'll head over to the GitHub today!

Anders • 12 years ago

Can you link to css files from templates? If so, how?

Ryan Niemeyer • 12 years ago

@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.

Murat Arslan • 11 years ago

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

Sebastian Negomireanu • 12 years ago

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.

Dan Andreescu • 12 years ago

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);
}

Ryan Niemeyer • 12 years ago

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.

eggshelly • 12 years ago

Thanks very much Ryan. Custom binding it is, and we look forward to future versions.

Jesse Hallam • 12 years ago

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.

mshwery • 12 years ago

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>
Ryan Niemeyer • 12 years ago

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.

mshwery • 12 years ago

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.

dũng • 12 years ago

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");
}

Micaël Félix • 11 years ago

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.

Micaël Félix • 11 years ago

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.

sd • 11 years ago

Ryan wrote: "Components can freely use other components in their template. That should open up a lot of interesting possibilities."

Micaël Félix • 11 years ago

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".

Michael • 11 years ago

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.

Ryan Niemeyer • 11 years ago

@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.

Micaël Félix • 11 years ago

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?

John Farrar • 11 years ago

What is the progress update on the 3.2 update?

Ryan Niemeyer • 11 years ago

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.

pbouzakis • 11 years ago

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.

Ryan Whitmire • 11 years ago

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 Niemeyer • 11 years ago

Ryan Whitmire - good to hear! Disposal / clean-up is very important in SPA development.

Shay Doherty • 11 years ago

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 ?

Ryan Niemeyer • 11 years ago

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.

sohi • 11 years ago

http://stackoverflow.com/qu... can you lease answer this