Issue with ListViewItemBinder.refresh() change in 2015.3.930

6 posts, 0 answers
  1. Artie
    Artie avatar
    29 posts
    Member since:
    May 2015

    Posted 31 Mar Link to this post

    I've been chasing down an elusive problem for some time now and I've narrowed it to a logic change in the ListViewItemBinder.refresh() method between Kendo UI versions 2015.2.902 and 2015.3.930 (the issue happens on every version since 2015.3.930).  We have a mobile list view that is bound to a data source.  The template for the ListView creates a Touch widget and a tap handler for each list item.  The tap events and event handlers are working just fine, within this tap handler we change several properties on the data items within the DataSource.  The issue is that in v2015.2.902 these property changes cause the ListView to refresh itself and properly reflect those property changes, but in 2015.3.930 the ListView does *not* refresh itself even though the code has not changed on our end.

    I finally managed to isolate the issue to a logic change within ListViewItemBinder.refresh() between the two versions, specifically within the first "if" block.  Here's the logic in 2015.2.902:

    if (action === "itemchange" && !listView._hasBindingTarget()) {
      item = listView.findByDataItem(dataItems)[0];
      if (item) {
        listView.setDataItem(item, dataItems[0]);
      }
      return;
    }

    In 2015.2.902, action === "itemchange" resolves to true and !listView._hasBindingTarget()) resolves to false, so this block is skipped.  The code eventually drops to the following if/else if/else blocks and eventually calls the very last "else" block which actually triggers the kendo code that re-executes the template and replaces the HTML content (comment is mine):

    if (action === "add" && !groupedMode) {
        var index = view.indexOf(dataItems[0]);
        if (index > -1) {
            addedItems = listView.insertAt(dataItems, index);
            addedDataItems = dataItems;
        }
    } else if (action === "remove" && !groupedMode) {
        addedItems = [];
        listView.remove(dataItems);
    } else if (groupedMode) {
        listView.replaceGrouped(view);
    }
    else if (prependOnRefresh && !listView._filter) {
        addedItems = listView.prepend(view);
        addedDataItems = view;
    }
    else {
        listView.replace(view); // <-- This is where the template is re-executed
    }

    However, in v2015.3.930, the first "if" block I listed earlier was re-written as follows:

    if (action === "itemchange") { // action is indeed "itemchange"
        if(!listView._hasBindingTarget()) { // This evaluates to false
            item = listView.findByDataItem(dataItems)[0];
            if (item) {
                listView.setDataItem(item, dataItems[0]);
            }
        }
        return; // We hit this return statement, thus the "refresh" block is never called
    }

    As I mentioned in the comments, this logic change causes us to immediately hit the "return" statement and we never drop into the lower if/else if/else block where the template gets re-executed.  My questions then are as follows:

    1. What exactly was the purpose of this change?
    2. Is the scenario I've laid out actually exposing a bug, or is there something that I'm doing incorrectly that I can resolve within my own code?

    I've tried to mock up this scenario in the Dojo but as of yet haven't quite been able to do it, hence the long post.  Thanks for taking a look!

  2. Petyo
    Admin
    Petyo avatar
    2438 posts

    Posted 05 Apr Link to this post

    Hi,

    the change you refer to is related to a feature improvement. In a nutshell, we don't re-render the template if an item is changed and the list is MVVM bound. This (apart from being more performant) resolves several cases with bound forms in a listview. 

    the easiest way to overcome this is to rely exclusively on MVVM bindings for the logic in the template, and avoid the #= # syntax. 

    Regards,
    Petyo
    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. Artie
    Artie avatar
    29 posts
    Member since:
    May 2015

    Posted 05 Apr Link to this post

    Hi Petyo, thanks for the reply.  I seem to recall I was using the #= # syntax in the first place because I was having trouble getting MVVM binding to work, but I decided to try your suggestion.  It looks like the text and tap event bindings are working, but something's wrong with the "css" binding.  I've mocked up a sample in the Dojo that illustrates the exact problem I'm seeing.  When you "tap" on one of the items the console properly reflects the property change but it's not reflected in in the styles of the element itself (they should toggle red).  Can you please take a look?  This is exactly what I'm seeing within my application using the 2016.1.226 version of Kendo UI.

    http://dojo.telerik.com/@artie.cs/EliBO

  5. Petyo
    Admin
    Petyo avatar
    2438 posts

    Posted 05 Apr Link to this post

    Hello Arthur,

    the problem is caused by the css binding not working on a widget element (the one with the data-role=touch). Moving it to another element will make it work as expected - like this. Does this work for you?

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  6. Artie
    Artie avatar
    29 posts
    Member since:
    May 2015

    Posted 05 Apr Link to this post

    I can probably restructure my HTML to get this to work.  Is the fact that CSS binding doesn't work on touch widgets working as intended?  If so, are there other properties that also don't work?  I was looking through the documentation and didn't see anything, so I thought I would ask.

    Thanks!

  7. Petyo
    Admin
    Petyo avatar
    2438 posts

    Posted 06 Apr Link to this post

    Hello,

    The implementation is intentional, although, from what I see, inconvenient in certain cases. the MVVM logic detects that the element is a widget, and from there on perfroms only the widget-specific bindings, which don't include the CSS one. This makes sense for a complex widget like the grid or the dropdowns, because it is not clear to which element the CSS should be applied.  

    Another thing which won't work for a widget element is the DOM event bindings (mouseover/out/down). I will make sure that we should document that, to avoid such confusion.

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready