New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: sprintf like usage #2586
Comments
Use Handlebars for such a task, sth. like this (not tested) // in HTML: <input type="text" data-bind="value: observableUserString">
var viewModel = {
observableUserString: ko.observable("{{status.percent}}%, {{status.completion}}")
status: ko.observable({ percent: 50, completion: 100 })
}
viewModel.compiled = ko.pureComputed(function() {
try {
return Handlebars.compile(viewModel.observableUserString()({ status: viewModel.status() })
} catch (err) {
return 'There was an error with your template string';
}
}) |
Thanks for the response, I will look in to that. |
I don't think using a Handlebars to parse the literal answers the question as to how to tap into Knockout's internals to leverage it's native parsing and tracking and context-hierarchy. Also this only works under the assumption that you know what data is going to be used in the literal and pass it in. The correct way to access all the Knockout "under the hood" magic is by creating custom bindings. A working example of your case here: The actual custom binding: ko.bindingHandlers.literal = {
init: function(elem, valueAccessor) {
return { controlsDescendantBindings: true };
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
const literal = ko.unwrap(valueAccessor());
const regex = /({([\w\.]*)})/gm;
const subst = '<span data-bind="text: $2"></span>';
const result = literal.replace(regex, subst);
ko.utils.setHtml(element, result);
ko.applyBindingsToDescendants(bindingContext, element);
}
}; Beware that this is a very quick and dirty example. You could use any form of parsing of your literal (including Handlebars) and create any type of binding. I chose to rewrite it as text-bindings, but that may not be the best solution. There are many ways to achieve the same effect. Maybe create a Computed and use the output of that as HTML, etc, etc. You would use it as follows: <div data-bind="literal: userTemplate"></div>
<input data-bind="value: userTemplate" /> Anyway, using custom bindings, you can use everything within the context (including $parent, etc) in your templates and all of Knockout's parsing and tracking (as long as you convert it correctly in your custom binding). Regards |
I, as a Knockout beginner, am facing this challenge:
I have a data object
And want to give the user the ability to define his own template strings like
"{status.percent}%, {status.completion}"
.After the conversion, this should result in
80%, 0.8
.The data object aswell as my template string are handled by javascript.
Ideal would be some function like
replaceVariables(formatString, dataObject)
.data-bind
?{.*}
from the template string myself, and write the object mapping logic myself?AFAIK Knockout uses data-bind attributes, which differ from my application a bit, since I don't want to make the user write HTML...
Thanks for the great work so far, and for the support.
The text was updated successfully, but these errors were encountered: