JavaScript inside KO template

How do I put a script inside a knockout pattern?

This does not 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 I am trying to run inside each of the elements that I use some-template

. The script can be modified, but I would prefer to use the original version.

+3


source to share


1 answer


What you want is not possible. I don't think that tags script

with executable javascript inside the text/html

script will have their code executed when the template is rendered.

However, like other commenters, you shouldn't do this. Fix your design, use Knockout functions for things like this. There are several alternative solutions, including:

Create your own bindHandler to activate the widget on the rendered template. You've only posted a small portion of the code, but here's what it 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 -->
      

Run codeHide result




Alternatively, use the afterRender

anchortemplate

attribute like:

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 -->
      

Run codeHide result


+4


source







All Articles