Search code examples
knockout.jsforeachknockout-templating

Combine knockout template foreach with data


I want to display several URLs in table and put a remove button next to each one. Since this is used on several places I decided to use knockout templating.

<script type="text/html" id="new-repo-template">
  <tr class="row">
    <td class="url-cell"
        data-bind="text: repo.url"></td>
    <td class="button-cell">
        <button data-bind="click: removeUrl">X</button>
    </td>
  </tr>
</script>

<table>
  <tbody data-bind="template: {name: 'new-repo-template',
                               foreach: myDataCollection, as: 'repo',
                               data: {removeUrl: myFunctions.removeRepo } }">
  </tbody>
</table>

Problem is that I need to combine foreach where I want to provide data and function call which is stored in myFunction object which is not part of myDataCollection.

Is it possible to combine this foreach with collection data and data object where is static and common properties for all collection objects?

Current setup where I have foreach next to data binding causes that data is not set and the property removeUrl is unknown.


Solution

  • Is it possible to use a basic template, moving your foreach data into the data property and invoking the iteration with the containerless foreach syntax. Since the template is scoped to data, you can then use $parent to access the function.

    <script type="text/html" id="new-repo-template">
      <tr></tr>
     <!-- ko foreach: collection -->
      <tr class="row">
        <td class="url-cell" data-bind="text: url"></td>
        <td class="button-cell">
         <button data-bind="click: $parent.removeUrl">X</button>
        </td>
      </tr>
     <!-- /ko -->
    </script> 
    
    <table>
      <tbody data-bind="template: {name: 'new-repo-template',
                                   data: {collection: myDataCollection,  
                                          removeUrl: myFunctions.removeRepo } 
                                  }"> 
     </tbody>
    </table>
    

    Note: Without the empty <tr>, the data within the foreach isn't marked up properly. Not quite sure what is going on with that.


    Fiddle