Mixing knockout templates with durandal compose

3,204 views
Skip to first unread message

miket

unread,
Mar 6, 2013, 1:24:21 PM3/6/13
to duran...@googlegroups.com
I have some existing knockout heavy views I'm trying to bring into my project. I have two cases I'm not sure about. Any suggestions or pointers to relevant sections of the documentation?

1. Edit/View templates for a single view model. I need to change the view based on an observable boolean. I noticed the mention of areas in the composition docs. I also see the viewStrategy bits, I'm just not sure where to go from there.

2. I have some small templates that change a form based on the type of a property and an operator. Datepicker gets rendered for a date, etc. Greater than, equal, is in list etc are the operators. There are a few of these and they are generally very small. My first thought was to leave these as knockout template bindings. I wanted to avoid including these knockout templates as a separate script file that's loaded into the dom when the page is first rendered. I tried including them in the view that contains the template binding but they aren't found at that point. Thinking about that a little more I assume that durandal loads the view but the binding happens before the templates are in the dom? This is an example of one of my views that has the problem:
<div>
<div data-bind="template: templateName"></div>
<script id="abc-template" type="text/html">
</script>
<script id="xyz-template" type="text/html">
</script>
</div>

Joseph Gabriel

unread,
Mar 6, 2013, 1:32:48 PM3/6/13
to duran...@googlegroups.com
regarding point 1: 
Anywhere in your view, you can include a mini-composition like this:  
    <div data-bind="compose: myTemplateSelector()"></div>

Then in your view model, you can create a myTemplateSelector property that can specify the view id to use:
        myTemplateSelector = ko.computed(function () {
            if (myCondition) {
                return "template1.html";
            }
            return "";
        });

Christian Droulers

unread,
Mar 13, 2013, 1:08:49 PM3/13/13
to duran...@googlegroups.com
What about point 2?

I've establish that the ko.applyBindings is called before the DOM is updated with the activeItem's view, but I don't think I want to use a full-on composition view for a simple recursive template.

My template looks like


Is there a way to late-bind the template? Is there a way to use composition without having a separate file?

Christian Droulers

unread,
Mar 13, 2013, 1:12:11 PM3/13/13
to duran...@googlegroups.com
Template looks like:


<script id="EntityTemplate" type="text/html">
  <tr><td data-bind="text: Name"></td></tr>
  <!-- ko foreach: { data: Children, as: 'child' } -->
  <!-- ko template: { name: EntityTemplate, data: child } -->
  <!-- /ko -->
  <!-- /ko -->
</script>

Rob Eisenberg

unread,
Mar 13, 2013, 1:18:51 PM3/13/13
to Christian Droulers, duran...@googlegroups.com
Right now, composition requires a separate file.


--
You received this message because you are subscribed to the Google Groups "DurandalJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to durandaljs+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Rob Eisenberg,
President - Blue Spire
www.durandaljs.com

Christian Droulers

unread,
Mar 13, 2013, 1:48:04 PM3/13/13
to Rob Eisenberg, duran...@googlegroups.com
And templates are impossible to use unless they are called by an observable's change event. Correct?

I just tried to use composition, and I couldn't use a foreach in the view. I also couldn't get the recursion to work more than one level. Any pointers or tutorials I can read on this?

Rob Eisenberg

unread,
Mar 13, 2013, 1:56:34 PM3/13/13
to Christian Droulers, duran...@googlegroups.com
Can you show me your code please?

Christian Droulers

unread,
Mar 13, 2013, 2:32:16 PM3/13/13
to Rob Eisenberg, duran...@googlegroups.com
Template call:

        <!-- ko foreach: { data: invoice().Entities, as: 'entity' } -->
        <tbody>
            <!-- ko template: { name: 'EntityTemplate', data: entity } -->
            <!-- /ko -->
        </tbody>
        <!-- /ko -->


Template:

<script type="text/html" id="EntityTemplate">
    <tr>
        <td colspan="6" data-bind="text: Name, css: Type"></td>
    </tr>
    <!-- ko foreach: Items -->
    <tr>
        <td data-bind="text: Quantity"></td>
        <td data-bind="text: OfferName"></td>
        <td data-bind="text: Sku"></td>
        <td data-bind="textMoney: UnitPrice" class="money"></td>
        <td data-bind="textMoney: TotalPrice" class="money"></td>
        <td></td>
    </tr>
    <!-- /ko -->
    <tr data-bind="if: Type() == 'InvoiceOrganization'">
        <th colspan="6" data-bind="textMoney: SubTotal" class="money"></th>
    </tr>

    <!-- ko foreach: { data: Entities, as: 'entity' } -->
    <!-- ko template: { name: 'EntityTemplate', data: entity } -->
    <!-- /ko -->
    <!-- /ko -->
</script>

This says it can't find the template with ID EntityTemplate, which is normal.

But if I put the template content on in a view and use compose instead, it renders Quantity as null. Also, it should render a second level of "entities", but it doesn't. I'm assuming it's because Entities is also null (since all properties seem to be), it will work.

I used compose as follows:

<!-- ko compose: { model: entity, view: 'views/partners/invoices/_entity.html' } -->
<!-- /ko -->

I followed the samples as closely as possible. It's probably something stupid. When I have time later, I'll try to start from a smaller use-case and use compose properly.

It would be a nice feature to use knockout's templates during activation of a view. They work after!

Christian Droulers

unread,
Mar 20, 2013, 1:11:17 PM3/20/13
to Rob Eisenberg, duran...@googlegroups.com
I've figured out compose. I just had a problem with variable scoping when calling it. Sorry for the late reply!

Rob Eisenberg

unread,
Mar 20, 2013, 1:12:44 PM3/20/13
to Christian Droulers, duran...@googlegroups.com
Glad you got it figure out! I somehow lost track of this question...
Reply all
Reply to author
Forward
0 new messages