Template does not fully update

5 posts, 0 answers
  1. Dr.YSG
    Dr.YSG avatar
    210 posts
    Member since:
    Dec 2009

    Posted 16 Dec 2013 Link to this post

    (I am NOT saying this is a bug, What I am saying is my brain needs training :-) )

    I have a TABLE that is DataBound to an ObservableArray (called vm.ServerData).

    <div id="ServerTable" class="row Block InfoTable ">
        <table>
            <thead>
                <tr>
                    <th>ACTION</th>
                    <th>Type</th>
                    <th>Class</th>
                    <th>Status</th>
                    <th>Size</th>
                </tr>
            </thead>
            <tbody data-bind="source: ServerData"
                   data-template="serverTemplate"></tbody>
        </table>
    </div>
    The body of the table is bound to the values in the Array via the data-template as follows:

    01.<script type="text/x-kendo-template" id="serverTemplate">
    02.    <tr data-path="${Path}"
    03.        data-filecount="${FileCount}"
    04.        data-maxzoom="${MaxZoom}"
    05.        data-date="${Date}"
    06.        data-type="${Type}">
    07.        #if(Newer == "NEW") { #
    08.        <td><div class="button radial Center ButtonText">Download</div></td>
    09.        #} else { #
    10.        <td title="Already Downloaded"><img src="../images/pushPin.png" style="width: 32px; height: 32px;" /></td>
    11.        #}#
    12.        <td><span data-bind="text: Type" /></td>
    13.        <td><span data-bind="text: Class" /></td>
    14.        <td><span data-bind="text: Newer" /></td>
    15.        <td><span data-bind="text: Size" /></td>
    16.    </tr>
    17.</script>


    Everything works fine the first time the page is entered. The issue is that the user can issue commands that update the ServerData[i[.Newer field.

    They update is done in code as follows:

    if ((dd.Type == sd.Type) && (dd.Date >= sd.Date)) {
        vm.ServerData[i].set("Newer", "CURRENT");
    }

    What I observe, is that the TD (line #14) updates just fine. But the IF/THEN/ELSE  condition (lines 7-11) is not getting executed. [What is odd is that lines #7-11 are executing properly the first time the page is updated. So it is clearly that the change from the text of "NEW" -> "CURRENT" in via SET() that is not firing a change in the template code.

    OK,

    I can do a crude force of the issue by adding  line #4 below:

    1.       if ((dd.Type == sd.Type) && (dd.Date >= sd.Date)) {
    2.            vm.ServerData[i].set("Newer", "CURRENT");
    3.        }
    4.kendo.bind($("#ServerTable"), vm.ServerData);
    And this will force the IF/THEN/ELSE to execute and my page works. But I think I am doing something very brutal to the KENDO MVVM paradigm (actually,
    I am violating the whole MVVM concept). So pray tell, What is the elegant way to do this?




  2. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 18 Dec 2013 Link to this post

    Hi,

    The content should be bound in order for it to be rendered again when the value changes. In the particular scenario you could use source:
    <script type="text/x-kendo-template" id="newerCellTemplate">   
        #if(Newer == "NEW") { #
            <div class="button radial Center ButtonText">Download</div>
        #} else { #
            <img src="../images/pushPin.png" style="width: 32px; height: 32px;" />
        #}#
    </script>
    <script type="text/x-kendo-template" id="serverTemplate">
        <tr>
            <td data-bind="source: this" data-template="newerCellTemplate"></td>      
            <td><span data-bind="text: Type" /></td>
            <td><span data-bind="text: Class" /></td>
            <td><span data-bind="text: Newer" /></td>
            <td><span data-bind="text: Size" /></td>
        </tr>
    </script>

    or html binding for the cell content:
    var viewModel = kendo.observable({
        newerContent: function (e) {          
            if (e.get("Newer") == "NEW") {
                return '<div class="button radial Center ButtonText">Download</div>';
            }
            else {
                return '<img src="../images/pushPin.png" style="width: 32px; height: 32px;" />';
            }
        }
    <script type="text/x-kendo-template" id="serverTemplate">
        <tr>       
            <td data-bind="html: newerContent"></td>


    Regards,
    Daniel
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Kendo UI is VS 2017 Ready
  4. Dr.YSG
    Dr.YSG avatar
    210 posts
    Member since:
    Dec 2009

    Posted 19 Dec 2013 Link to this post

    Thank you Daniel,

    However, as a coding preference, I want all the HTML (declaritive layout and content) to be in the HTML files, and for MVVM, to have the semantics and business logic in the VM layer. So for me, it is cleaner to just rebind the observable array after I update the items in it, than to have code that manipulates the DOM. The only DOM manipulation I tend to do is change DOM element classes(new styles, animation,etc.)

    Just a FYI, to pass back to Telerik when you look at the mechanics of how you template and when you update.

  5. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 21 Dec 2013 Link to this post

    Hello,

    Indeed the template isn't updated when the data item is changed (for performance reasons). This is why you need to use bindings (data-bind) in order for the UI to get updated.

    We can offer a different solution - to use the visible binding and hide parts of the UI which are not needed:

    <script type="text/x-kendo-template" id="serverTemplate">
        <tr>
            <td>
              <div data-bind="visible: isNew" class="button radial Center ButtonText">Download</div>
              <img data-bind="visible: isNotNew" src="../images/pushPin.png" style="width: 32px; height: 32px;" />
            </td>
            <td><span data-bind="text: Type" /></td>
            <td><span data-bind="text: Class" /></td>
            <td><span data-bind="text: Newer" /></td>
            <td><span data-bind="text: Size" /></td>
        </tr>
      </script>

    Here is a live demo: http://jsbin.com/uKImuMOg/1/edit

    Regards,
    Atanas Korchev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Dr.YSG
    Dr.YSG avatar
    210 posts
    Member since:
    Dec 2009

    Posted 23 Dec 2013 Link to this post

    Yes, this is a nice clean solution.

    Here is something I thought about (yea, free ideas are worth exactly that :)

    BTW: If you are looking for feature ideas, consider allowing a person to "tag" a template as "live", and then register it for the change events for any data bound MVVM data. The global overhead would not increase, but if a MVVM value did change then it would have to fire a change event to the live template to be re-run. But that would be something the developer to regulate.

    The idea is to take your powerful scripting capability for templates, and make them something that can make a continuous adapting UX experience driven by data  (I work in big data, so I constantly need to weed and filter data and present different information displays that are succint for the current set of data).

Back to Top
Kendo UI is VS 2017 Ready