Reputation: 637
I am thinking of using Knockout.js to create reusable components. However, by reading the docs, I don't know how would I implement a component that can hold other (potentially different with each use) components inside it.
For example, I would like to implement a side-menu-view component, which would contain a title bar with menu button, a menu panel, and a content panel. The contents of the menu and content panels should not be defined in advance. For example, in one use case I would put a list-view component into the menu panel, in another use case I could put a list of checkboxes into the menu panel.
As what I understand from the docs, in Knockout.js the template of a component must be defined fully, and does not offer places where other components could be inserted later. Or am I wrong? Can it be done? Thanks!
UPDATE:
I want to create a component , which could be used as:
<side-menu-view>
<menu>
<!-- I can put anything here -->
</menu>
<content>
<!-- I can put anything here -->
</content>
</side-menu-view>
I understand the child nodes of a component can be accessed via $componentTemplateNodes, but then I want to be able to get the contents of <menu>
and <content>
separately, and put it within the appropriate places of my component layout.
UPDATE 2:
Example use:
<side-menu-view>
<menu>
This is a menu!
</menu>
<content>
This is content!
</content>
</side-menu-view>
Or like this:
<side-menu-view>
<menu>
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
</menu>
<content>
<h1>Title</h1>
<p>Some text</p>
</content>
</side-menu-view>
Upvotes: 0
Views: 227
Reputation: 13549
If you're using the custom html element syntax, then you're right, you have to know the components when you write your html, like so:
<menu-panel>
<list params="..."/>
</menu-panel>
However, you have the component binding which lets you choose the component at run time:
<menu-panel>
<div data-bind="component: {
name: yourDynamicComponentName,
params: { ... },
}"/>
</menu-panel>
Note, of course, that yourDynamicComponentName
must still be registered so knockout knows where to find it.
RE: Update 2 (focusing only on the menu
control as it's obviously similar for the content
control):
So you just define two components, one called menu-list
and one called menu-static
:
// html for a component called "menu-list"
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
</ul>
// html for a component called "menu-static"
This is a menu!
And in your viewModel
for side-menu-view
you can have a property called menuType
, and you would use it in the html for side-menu-view
like this:
// html for "side-menu-view"
<div data-bind="component: { name: menuType }"/>
So now you can set menuType('menu-static')
or menuType('menu-list')
when you want to toggle between menu types.
Upvotes: 1
Reputation: 1769
A knockout's model can be "pre-defined" for common usage and then extended for particular purpose. This means:
Example:
var mainModel = function () {
this.blablabla = ko.observable('blablabla');
}
var extendedModel = function () {
this.sup = ko.observable('sup');
}
var myModelInstance = $.extend({}, new mainModel(), new extendedModel());
console.log(myModelInstance.blablabla(), myModelInstance.sup()); // "blablabla", "sup"
Upvotes: 0