How to call a nested function from out side knockout js

339 views Asked by At

i am learning knockout js. so still my understanding is not very clear. so apologized to ask this kind of question.

see the code first to see what i am trying to achieve. here is jsfiddle link http://jsfiddle.net/tridip/vvdvgnfh/

<button data-bind="click: $root.printproduct()">Print Product</button>
<table id="table1" cellspacing="0" cellpadding="0" border="0">
    <tr>
        <th style="width:150px">Product</th>
        <th>Price ($)</th>
        <th>Quantity</th>
        <th>Amount ($)</th>
    </tr>

    <tbody data-bind='template: {name: "orderTemplate", foreach: lines}'></tbody>
</table>

<script type="text/html" id="orderTemplate">
    <tr>
        <td><select data-bind='options: products,
                               optionsText: "name",
                               optionsCaption:"--Select--",
                               value: product'>
                               </select>
        </td>

        <td>
            <span data-bind='text:price' ></span>
        </td>
        <td>
            <input data-bind='value:quantity' />
        </td>

        <td ><span data-bind='text:subtotal()'></span></td>

    </tr>
</script>    

var CartLine = function () {
          var self = this;
          self.products = ko.observableArray(_products);
          self.product = ko.observable(1);
          self.price = ko.observable(1);
          self.quantity = ko.observable(1);  
          self.product.subscribe(function(item){
              if(!item)
              {
                 self.price(0);
                 self.quantity(0);
                 return;
              }
             self.price(item.price);
             self.quantity(item.quantity);
          });

          self.subtotal = ko.computed(function () {

              return self.price() * self.quantity();
          },self);

        self.printproduct = function() {
             alert('hello');
        }            
      };

      var Cart = function () {
          // Stores an array of lines, and from these, can work out the grandTotal
          var self = this;
          self.lines = ko.observableArray([new CartLine()]); // Put one line in by default


      };

      ko.applyBindings(new Cart());

Print Product is a out side button but if i need to call a function which is defined in CartLine then how could i access ? is it at all possible ?

thanks

1

There are 1 answers

0
omerio On BEST ANSWER

You can't call a function on CartLine outside the loop as it's outside the context (scope), one approach you can follow is to have a click binding on the row, when the user clicks the row, it calls a function on the root scope to save a reference to the selected cartline:

 <tr data-bind="click: $root.selectRow">
    <td><select data-bind='options: products,

and the Cart function now has a selectRow and a print functions:

  var Cart = function () {
      // Stores an array of lines, and from these, can work out the grandTotal
      var self = this;
      self.lines = ko.observableArray([new CartLine()]); // Put one line in by default
      self.selectRow = function(line) {
          self.selected = line;
      }

      self.print = function() {
          if(self.selected) {
              self.selected.printproduct();
          }
      }
  };

then the print button simply calls the print function on the root which delegates to the selected cartline

<button data-bind="click: $root.print">Print Product</button>

Here is an update jsFiddle http://jsfiddle.net/omerio/vvdvgnfh/1/