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

Remote Views + querystrings: odd behaviour

7 Answers 261 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Fredrik
Top achievements
Rank 1
Fredrik asked on 03 May 2012, 04:24 PM
Hi!

Relatively new to KendoUI, we're currently evaluating this along with a few other frameworks for html5-mobile-development. 
So far, I really like the KendoUI approach, with templating and datasourcing etc. But, one thing sticks out as a little odd.

When using Remote Views with querystrings, I'm experiencing odd behaviour. First I thought it was down to caching, so I started adding a random querystring to each remote view link, but that only furthered the problem.

Inspecting the Html DOM with firefox DOM Inspector or firebug lead me to the right track however:

A remote view is normally just added once, and re-used. I see the point of that. Until it has querystrings - then each unique permutation is added as a DOM element (due to mismatching data-url?) , leading to massive problems. Not only in things not properly working ( i.e. trying to $("#elem").kendoMobileListView( )  will / may fail, or populate a listview in a completely different, hidden, view) but it also leads to unnecessary memory usage, and general browser slowness. Depending on the complexity of the views, naturally.

However, it was relatively easy to fix. I just had to make sure I killed off any divs, script templates or other unique stuff in the event handler run on the views data-hide event. ( $(elm).destroy(); $(scriptelm).destroy(); )

I've attached an illustration. Green = behaving normally. Red boxes - not behaving as I would have presumed. All views except the 'root' view are remote. 

But, my question: Is this behaviour by design or is it a bug? I had figured that once a view had been loaded, it would be re-used, data-init would be used to clean/scrub and fetch new query string parameters and then data-show would take care of data-binding etc.

7 Answers, 1 is accepted

Sort by
0
Accepted
Petyo
Telerik team
answered on 03 May 2012, 05:04 PM
Hello,

Thanks for contacting us. The behavior you describe is by design. Remote views are reused only if the URL (including the query string) is identical.

I agree that this behavior may be counter intuitive in certain cases, but the other way around would require erasing the previously loaded remote view contents - which may baffle people who expect the previously loaded page to be available once requested. 

In general, the best performance is achieved with lightweight local views that act like placeholders, while using the Kendo UI DataSource Component and external services for data transfer, UI updates and CRUD operations. 

Kind regards,
Petyo
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Fredrik
Top achievements
Rank 1
answered on 03 May 2012, 08:10 PM
Hi Petyo,

Thanks for clarifying. Good to know. Then I'll keep at the praxis of destroying my views + associated templates on data-hide (if that's an acceptable behaviour - it seems to work). The alternative - merging most remote views into core isn't very practical, since we try to build on a more modular basis and not necessary touch/modify more than actually required based on future customer customization requirements. 

(It's already heavily reliant on DataSources, templates and ajax-json-data-calls... Which is why I like it :) )
0
Petyo
Telerik team
answered on 04 May 2012, 09:50 AM
Hi,

So you remove the view element on the hide event? Now that is a clever trick! Hadn't thought about it before. Thanks for sharing it.  

Regards,
Petyo
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Fredrik
Top achievements
Rank 1
answered on 26 Sep 2012, 11:03 PM
Late reply, but figured someone else may run into the same issue(s).

Yes - I resorted to killing loaded remote views + scripts through the data-hide-events. There really was no other way. 

I understand the logic behind the decision to cache loaded remote views - but in instances where there can be literally hundreds of querystring combinations (categories in e-commerce, product id's) etc, the sheer size of the resulting DOM becomes unmaintanable and causes severe instability/slowness - especially in mobile clients.

But, worth remembering is that even with killing certain bits, there are still dangling references to other things. 

These are some experiences I've picked up over the last few months. Most of them, if not all, are reproducible in both v2012.1.322 and v2012.2.710.

Case in point, a simple (remote) view:

<div id="StoreCategories"
data-role="view"
data-init="initStoreCategories"
data-hide="destroyStoreCategories"
data-show="showStoreCategories"
data-layout="mobile-view
>
 
<script id="cStoreCategoriesTemplate" type="text/x-kendo-template">
...
</script>
 
<ul id="StoreCategory_listview" data-style="inset"></ul>

// this runs in the first loaded master view
window.kendoMobileApplication = new kendo.mobile.Application($(document.body), { ...

A simple remote view containing a list, a template and some javascript event handlers. 

Simply doing:
function destroystorecat(e){
 $("#cStoreCategoriesTemplate").remove();
 $("#StoreCategories").remove();
}

... is not enough. It may appear so, but not really. First time the view is loaded, it looks fine. Second time, with same or different parameters - the view won't quite be right - there'll be something off. Perhaps grouping doesn't work. Perhaps all code in the data-show or data-init doesn't run as expected..
Calls to elements in the template through $("something") will sometimes not quite do what you expect.

Reasons?

$("#StoreCategory_listview").kendoMobileListView({
 ....
});

$('#Headline').text('This is a headline');

Despite the view itself and it's associated child elements have been erased from the DOM, there are likely still references to elements elsewhere. So either kill them fire/nuke them from orbit. Or, simply do it the right way:

e.view.element.find("#StoreCategory_listview").kendoMobileListView({
 ...
});

e.view.element.find('#Headline').text('This is a headline') 


Also, when dealing with remote views, the following two statements are not equal:

function datashowCategories(e) {
 // case #1
  var app = window.kendoMobileApplication;
  var myQSVariable = app.view.params.category_id; //results in "app.view.params.category_id is undefined"
  app.view.element.find("#show_id").text( myQSVariable  ); //results in "app.view is undefined"
 
 // case #2
     var myQSVariable = e.view.params.category_id;
     e.view.element.find("#show_id").text( myQSVariable  );
}

Case #1 above frequently (on secondary loads of the same remote view) fails without notice. Or fails with app.view is undefined. It seems that the view goes out of scope (?).
Case #2 always works, so if you need to access  the current view from a function that's not directly called through data-init, data-show etc, make sure to pass along e as an argument to them. 

tl;dr: Never use a straight $("#element") unless you can guarantee that the view either only loads once, you aren't using the same id in a different view or that you don't have any dangling references from other sources. Also, do not put absolute trust in window.kendoMobileApplication. Always rely on the event data instead.



0
Matt
Top achievements
Rank 1
answered on 09 Oct 2012, 10:40 AM
This was my solution for clearing out old remote views

cleanKendoViews: function()
        {
            /* remove old form views */
            $('div[data-role=view]').each( function( i, elem )
            {
                if ( $(elem).attr('data-url') && $(elem).attr('data-url') != window.location.hash.replace( /#/, '' ) )
                {
                    $(elem).remove();
                }
            } );
        },
0
Stephen
Top achievements
Rank 1
answered on 15 Jan 2013, 09:23 AM
Thanks guys,

this saved my project
0
Eric
Top achievements
Rank 1
answered on 16 Feb 2014, 01:10 AM
Just make sure to do two things when using remote views:

- Do not use the same id for the data-template, i.e. use a different template id for each remote view you are using
- Use view.element.find("#id") instead of $("#id") when grabbing the listview

If you do the above two things, you should be fine. I have a working project with remote views and everything works as expected.
Tags
General Discussions
Asked by
Fredrik
Top achievements
Rank 1
Answers by
Petyo
Telerik team
Fredrik
Top achievements
Rank 1
Matt
Top achievements
Rank 1
Stephen
Top achievements
Rank 1
Eric
Top achievements
Rank 1
Share this question
or