Component Registration
Component Registration
Section titled “Component Registration”For TKO to load and instantiate a component, you register it with ko.components.register.
If your app needs to resolve components from files, naming conventions, or another lookup strategy, use a custom component loader rather than hiding that logic inside the registration format.
- [Table of contents injected here] {:toc}
Registering a component
Section titled “Registering a component”ko.components.register('some-component-name', { viewModel: <see below>, template: <see below>})- The component
namecan be any nonempty string. Lowercase dash-separated names such asyour-component-nameare recommended because they are valid custom element names too. viewModelis optional.templateis required.
If no viewmodel is given, the component is treated as a simple block of HTML that will be bound to any parameters passed to the component.
Specifying a viewmodel
Section titled “Specifying a viewmodel”Viewmodels can be specified in any of the following forms.
A constructor function
Section titled “A constructor function”function SomeComponentViewModel(params) { this.someProperty = params.something}
SomeComponentViewModel.prototype.doSomething = function() { ... }
ko.components.register('my-component', { viewModel: SomeComponentViewModel, template: ...})TKO creates a new viewmodel instance for each component instance.
A shared object instance
Section titled “A shared object instance”var sharedViewModelInstance = { ... }
ko.components.register('my-component', { viewModel: { instance: sharedViewModelInstance }, template: ...})Use this only when every component instance should share the same object.
A createViewModel factory function
Section titled “A createViewModel factory function”ko.components.register('my-component', { viewModel: { createViewModel: function(params, componentInfo) { return new MyViewModel(params) } }, template: ...})Use createViewModel when you want setup logic before the template is bound, or when you need access to componentInfo.element and componentInfo.templateNodes.
The componentInfo.templateNodes array is useful if you want to build a component that accepts arbitrary markup to influence its output, such as a grid, list, dialog, or tab set. See passing markup into components for a complete example.
Specifying a template
Section titled “Specifying a template”Templates can be specified in any of the following forms.
An existing element ID
Section titled “An existing element ID”<template id='my-component-template'> <h1 data-bind='text: title'></h1> <button data-bind='click: doSomething'>Click me right now</button></template>ko.components.register('my-component', { template: { element: 'my-component-template' }, viewModel: ...})Only the nodes inside the element are cloned into each component instance.
An existing element instance
Section titled “An existing element instance”var elemInstance = document.getElementById('my-component-template')
ko.components.register('my-component', { template: { element: elemInstance }, viewModel: ...})A string of markup
Section titled “A string of markup”ko.components.register('my-component', { template: '<h1 data-bind="text: title"></h1>' + '<button data-bind="click: doSomething">Clickety</button>', viewModel: ...})This is convenient when your build step already emits a template string or when a custom loader turns fetched markup into a string before converting it to DOM nodes.
An array of DOM nodes
Section titled “An array of DOM nodes”var myNodes = [ document.getElementById('first-node'), document.getElementById('second-node'), document.getElementById('third-node')]
ko.components.register('my-component', { template: myNodes, viewModel: ...})A document fragment
Section titled “A document fragment”ko.components.register('my-component', { template: someDocumentFragmentInstance, viewModel: ...})Additional component options
Section titled “Additional component options”Your component configuration object can include additional properties if a custom loader needs them. Those properties are passed through to the loader unchanged.
Controlling synchronous/asynchronous loading
Section titled “Controlling synchronous/asynchronous loading”If your component configuration has a boolean sync property, TKO uses it to determine whether the component is allowed to load and inject synchronously. The default is false.
Normally, TKO keeps component loading asynchronous because a loader may need to fetch files or data. That default avoids bugs where a process sometimes completes synchronously and sometimes asynchronously.
If you set sync: true, a component may load asynchronously the first time and synchronously on later uses if the definition is already cached. Use that carefully when your code depends on timing.