Company logo
  • Jobs
  • Bootcamp
  • About Us
  • For professionals
    • Home
    • Jobs
    • Courses
    • Questions
    • Teachers
    • Bootcamp
  • For business
    • Home
    • Our process
    • Plans
    • Assessments
    • Payroll
    • Blog
    • Calculator

0

99
Views
knockout.js can you access the binding context from a script?

I have a javascript object graph, an HTML form, and knockout bindings connecting the two. The form is complex, and sometimes the form needs to add some computed observables to some sub-object in our object graph, and I want to do that locally in the the HTML element that has the data-bind which relies on this, I don't want such knowledge somewhere in some global script.

<div class="widget" data-bind="foreach: subThing">
  <script type="text/javascript">
    $data._scratchpad = ko.computedObservable( ... );
  </script>
  ...
  <input data-bind="value: _scratchpad"/>
  ...
</div>

Now in the context of this script, the binding context is of course not yet set up, so the $data property is not yet available.

But is there some event that I might put on the element or something so I can catch when the bindings are first initialized so I can add the necessary things before the actual data-bind expressions want to refer to them?

7 months ago · Juan Pablo Isaza
1 answers
Answer question

0

I came up with a solution which is just a little ugly, but actually practically correct. Instead of this script element above, I just use a virtual element that contains nothing and whose only point is to get an if: condition evaluated, where then we put the statements into the body of a function that gets evaluated:

<div class="widget" data-bind="foreach: subThing">
  <!-- ko if: (function() { if(!$data._scratchpad) {
       $data._scratchpad = ko.computedObservable( ... );
       }})() --> <!-- /ko -->
  ...
  <input data-bind="value: _scratchpad"/>
  ...
</div>

The nice thing is that required no modification of the source code. And while it is just a little ugly with the boiler-plate code:

  <!-- ko if: (function() { if(!...) {
       ...
       }})() --> <!-- /ko -->

I could potentially use a custom binding's preprocessor to wrap this function around and say instead simply:

  <!-- ko setup: 
       ...
  --> <!-- /ko -->

this is almost neat, but really not so much better that it's worth it.

It's kind-a handy that this virtual element definition is already in a comment, so there won't be any worries with the javascript code using special characters.

7 months ago · Juan Pablo Isaza Report
Answer question
Find remote jobs