This is a migrated thread and some comments may be shown as answers.

Issue with ListViewItemBinder.refresh() change in 2015.3.930

7 Answers 45 Views
ListView (Mobile)
This is a migrated thread and some comments may be shown as answers.
Artie
Top achievements
Rank 1
Artie asked on 31 Mar 2016, 05:45 PM

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!

7 Answers, 1 is accepted

Sort by
0
Petyo
Telerik team
answered on 05 Apr 2016, 06:13 AM
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!
 
0
Artie
Top achievements
Rank 1
answered on 05 Apr 2016, 02:21 PM

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

0
Petyo
Telerik team
answered on 05 Apr 2016, 03:31 PM
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!
 
0
Artie
Top achievements
Rank 1
answered on 05 Apr 2016, 06:20 PM

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!

0
Petyo
Telerik team
answered on 06 Apr 2016, 06:11 AM
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!
 
0
Paolo
Top achievements
Rank 1
answered on 03 Jul 2019, 10:29 AM

Hi guys, we developed our derived version of ListView to handle such as scenario, and we DID it because we didn't know about that feature _hasBindingTarget !
For our case the scenario addressed by _hasBindingTarget is too restrictive, so we suggest to override it :

_hasBindingTarget: function () {
    return !!this.element[0].kendoBindingTarget;
},

 

for example this code check you item template to find any presence about a data-bind attribute :

 

_hasBindingTarget: function () {
    return this.element.find('[data-bind]').length > 0;
},

0
Boyan Dimitrov
Telerik team
answered on 05 Jul 2019, 09:33 AM
Hello,

Thank you for your suggestion. 

Indeed if such override works fine for your scenario you can override it in your code. Actually we are not planning to change it, because in some cases we need to be more restrictive in order to avoid issues and misbehavior.  

I believe that some people can find this workaround useful for their cases. 

Regards,
Boyan Dimitrov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
ListView (Mobile)
Asked by
Artie
Top achievements
Rank 1
Answers by
Petyo
Telerik team
Artie
Top achievements
Rank 1
Paolo
Top achievements
Rank 1
Boyan Dimitrov
Telerik team
Share this question
or