How to put script inside knockout template?
This doesn't work:
<script type="text/html" id="some-template">
<div>
...
<script type="text/javascript"> <!-- This is the problem -->
CoinWidgetCom.go({
wallet_address: "ENTER-YOUR-BITCOIN-WALLET-ADDRESS"
, currency: "bitcoin"
, counter: "count"
, alignment: "bl"
, qrcode: true
, auto_show: false
, lbl_button: "Donate"
, lbl_address: "My Bitcoin Address:"
, lbl_count: "donations"
, lbl_amount: "BTC"
});
</script>
...
</div>
</script>
...
<script src="http://coinwidget.com/widget/coin.js"></script>
This is the script that I'm trying to run inside each of the elements that use some-template
. Script could maybe be modified, but I would rather use original version.
What you want is not possible. I don't think script
tags with executable javascript inside a text/html
script will have their code executed when the template is rendered.
However, like other commenters said: you don't need to do this. Rework your design, make use of Knockout's features for these type of things. There are several alternative solutions, including:
Creating your own bindingHandler to activate the widget on a rendered template. You have posted only a small portion of code, but here's what that would look like:
ko.bindingHandlers.myWidget = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
// Set up any initial state, event handlers, etc. here
console.log('Initializing widget with ' + ko.toJSON(allBindings()['myWidget']));
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called once when the binding is first applied to an element,
// and again whenever any observables/computeds that are accessed change
// Update the DOM element based on the supplied values here.
}
};
var VmForTemplate = function() { }
var ViewModel = function() {
this.subVm = new VmForTemplate();
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script type="text/html" id="some-template">
<div data-bind='myWidget: {
wallet_address: "ENTER-YOUR-BITCOIN-WALLET-ADDRESS"
, currency: "bitcoin"
, counter: "count"
, alignment: "bl"
, qrcode: true
, auto_show: false
, lbl_button: "Donate"
, lbl_address: "My Bitcoin Address:"
, lbl_count: "donations"
, lbl_amount: "BTC"
}'>
... template ...
</div>
</script>
<!-- ko template: { name: 'some-template', data: subVm } -->
<!-- /ko -->
Alternatively, use the afterRender
attribute of the template
binding, like so:
var VmForTemplate = function() { }
var ViewModel = function() {
this.subVm = new VmForTemplate();
this.initWidget = function() { CoinWidgetCom.go({
wallet_address: "ENTER-YOUR-BITCOIN-WALLET-ADDRESS"
, currency: "bitcoin"
, counter: "count"
, alignment: "bl"
, qrcode: true
, auto_show: false
, lbl_button: "Donate"
, lbl_address: "My Bitcoin Address:"
, lbl_count: "donations"
, lbl_amount: "BTC"
}); };
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script type="text/html" id="some-template">
<div>
Template. No javascript here.
</div>
</script>
<script>
// Mock the widget
var CoinWidgetCom = { go: function(opts) { console.log('Running widget with options: ' + ko.toJSON(opts)); } };
</script>
<!-- ko template: { name: 'some-template', data: subVm, afterRender: initWidget } -->
<!-- /ko -->