Skip to content

Instantly share code, notes, and snippets.

@tscpp
Created September 27, 2020 14:05
Show Gist options
  • Save tscpp/36b8eb562fc5ff0a1c4b41c27c99ec8b to your computer and use it in GitHub Desktop.
Save tscpp/36b8eb562fc5ff0a1c4b41c27c99ec8b to your computer and use it in GitHub Desktop.
import * as ko from 'knockout';
export function register(name: string): void;
export function register(name: string, templatePath: string, viewModelPath: string | null, stylePath: string | null): void;
export function register(name: string, _templatePath?: string, _viewModelPath?: string | null, _stylePath?: string | null): void {
let templatePath: string;
let viewModelPath: string | undefined;
let stylePath: string | undefined;
if (_templatePath)
templatePath = _templatePath;
else
templatePath = `/components/${name}.html`;
if (_viewModelPath === null)
viewModelPath = undefined;
else if (_viewModelPath)
viewModelPath = _viewModelPath;
else
viewModelPath = `/components/${name}.js`;
if (_stylePath === null)
stylePath = undefined;
else if (_stylePath)
stylePath = _stylePath;
else
stylePath = `/styles/${name}.css`
return _register(name, templatePath, viewModelPath, stylePath);
}
function isPromise<T>(value: any): value is Promise<T> {
return typeof value === 'object' && 'then' in value;
}
const { loadTemplate, loadViewModel } = ko.components.defaultLoader;
ko.components.defaultLoader.loadTemplate = (name, config: ko.components.TemplateConfig | Promise<string>, callback) => {
if (isPromise(config))
config.then(config => loadTemplate(name, config, callback));
else
loadTemplate(name, config, callback);
};
ko.components.defaultLoader.loadViewModel = (name: string, config: ko.components.ViewModelConfig | Promise<ko.components.ViewModelConfig>, callback: (resolvedViewModel: ko.components.CreateViewModel) => void) => {
if (isPromise(config))
config.then(config => loadViewModel(name, config, callback));
else
loadViewModel(name, config, callback);
}
let stylesLoaded: string[] = [];
function _register(name: string, templatePath: string, viewModelPath: string | undefined, stylePath: string | undefined): void {
let viewModel: Promise<Function> | undefined = undefined;
if (viewModelPath)
viewModel = new Promise(resolve => requirejs([viewModelPath], resolve));
const template = new Promise<string>(resolve => requirejs([`text!${templatePath}`], resolve));
if (stylePath && !stylesLoaded.includes(stylePath)) {
const comment = document.createComment(`Loaded by component ${name}`);
document.head.appendChild(comment);
const linkEl = document.createElement('link');
linkEl.rel = 'stylesheet';
linkEl.href = stylePath;
document.head.appendChild(linkEl);
}
ko.components.register(name, {
viewModel,
template
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment