You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To give more context (based on the slack chat we had):
We need to be able to display sets of data with different "designs" in a ListView without the need of using collapsed views (like a huge template which will be impossible to maintain and cost CPU cycles) or logic inside the view-model for ContentView which would have performance penalties.
A good scenario could be a news app, that needs to display the news with different designs based on the importance of the article:
We would like to gather some ideas and feedback about how the public API for this feature might look like. All suggestions are welcome. Currently we are thinking along the lines of something like this:
<Page
xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
<ListView items="{{ people }}" itemTemplateSelector="{{ age % 2 === 0 ? '1' : '2' }}">
<ListView.itemTemplates>
<template key="1">
<Label text="{{ name + ' ' + age }}" style.backgroundColor="blue"/>
</template>
<template key="2">
<Label text="{{ name + ' ' + age }}" style.backgroundColor="red"/>
</template>
</ListView.itemTemplates>
</ListView>
</Page>
Reacted by Nikolay Iliev, Deyan Ginev, Vladimir Amiorkov and Panayot Cankov
@ginev Sounds very reasonable. Can you please show me how do you imagine the callback API. I want to gather as much concrete dummy code samples as possible.
@hamorphis something like that. Note that this will affect performance as in the normal case Views are cached and the bindingContext is changed. With this approach a new View will be created for each item. We might want to implement caching for separate templates.
The current Angular ListView directive doesn't use the template parser functionality. You'd ask why... because it has to use Angular templates which have their own bindings.
For the time being we use a somewhat hacky solution which handles the onItemLoading event, where it instantiates an Angular template, pulls the root view from inside, and passes it to the list view item.
It would be great if we use this feature to revisit our base template handling logic (possibly across the entire framework) and come up with a TS/JS API that allows us to programmatically register:
keyed templates: functions that return a View and have an associated key/id.
template selector function that accepts a data item (maybe item index as well) and returns a template key.
The above will allow the Angular implementation to discover all provided TemplateRef's, extract their keys, build template functions and pass those along with a selector function to the base ListView implementation.
On a side note... how does this affect RadListView? I gather we need the same (or a similar) API there.
@hdeshev RadListView suffers from the same illness regarding Angular 2.0 templates. We had to rewrite the logic that parses standard NS templates and binds them. Now, there is a callback that simply returns a ready View for an item. This is something similar to the suggestion done by @hamorphis above but without passing an index or data item as an argument:
this._listView.itemViewLoader = (viewType) => {
switch (viewType) {
case ListViewViewTypes.ItemView:
if (component._itemTemplate && this.loader) {
var nativeItem = this.loader.createEmbeddedView(component._itemTemplate, new ListItemContext(), 0);
var typedView = getSingleViewFromViewRef(nativeItem);
typedView["ng_view"] = nativeItem;
return typedView;
}
break;
case ListViewViewTypes.ItemSwipeView:
if (component._itemSwipeTemplate && this.loader) {
var nativeItem = this.loader.createEmbeddedView(component._itemSwipeTemplate, new ListItemContext(), 0);
var typedView = getSingleViewFromViewRef(nativeItem);
typedView["ng_view"] = nativeItem;
return typedView;
}
break;
case ListViewViewTypes.LoadOnDemandView:
if (component._loadOnDemandTemplate && this.loader) {
var viewRef = this.loader.createEmbeddedView(component._loadOnDemandTemplate, new ListItemContext(), 0);
var nativeView = getSingleViewFromViewRef(viewRef);
nativeView["ng_view"] = viewRef;
return nativeView;
}
break;
case ListViewViewTypes.HeaderView:
if (component._headerTemplate && this.loader) {
var viewRef = this.loader.createEmbeddedView(component._headerTemplate, new ListItemContext(), 0);
var nativeView = getSingleViewFromViewRef(viewRef);
nativeView["ng_view"] = viewRef;
return nativeView;
}
break;
case ListViewViewTypes.FooterView:
if (component._footerTemplate && this.loader) {
var viewRef = this.loader.createEmbeddedView(component._footerTemplate, new ListItemContext(), 0);
var nativeView = getSingleViewFromViewRef(viewRef);
nativeView["ng_view"] = viewRef;
return nativeView;
}
break;
}
};
We can build on-top of that to implement the Template Selector functionality.
Activity
hamorphis commentedon Sep 29, 2016
We would like to gather some ideas and feedback about how the public API for this feature might look like. All suggestions are welcome. Currently we are thinking along the lines of something like this:
rborn commentedon Sep 29, 2016
This format seems ok to me 😄
hamorphis commentedon Sep 29, 2016
Have in mind that we should somehow implement this for Angular too!
ginev commentedon Sep 29, 2016
Looks good to me too. @hamorphis what do you think about exposing a callback API to allow for returning a View instance to use for a particular item?
rborn commentedon Sep 29, 2016
@hamorphis you lost me here, I don't know Angular 😊
hamorphis commentedon Sep 29, 2016
@ginev Sounds very reasonable. Can you please show me how do you imagine the callback API. I want to gather as much concrete dummy code samples as possible.
hamorphis commentedon Sep 29, 2016
@ginev Something like this maybe?
And in the page code-behind file:
ginev commentedon Sep 29, 2016
@hamorphis something like that. Note that this will affect performance as in the normal case Views are cached and the
bindingContextis changed. With this approach a newViewwill be created for each item. We might want to implement caching for separate templates.hdeshev commentedon Sep 29, 2016
The current Angular ListView directive doesn't use the template parser functionality. You'd ask why... because it has to use Angular templates which have their own bindings.
For the time being we use a somewhat hacky solution which handles the
onItemLoadingevent, where it instantiates an Angular template, pulls the root view from inside, and passes it to the list view item.It would be great if we use this feature to revisit our base template handling logic (possibly across the entire framework) and come up with a TS/JS API that allows us to programmatically register:
Viewand have an associated key/id.The above will allow the Angular implementation to discover all provided TemplateRef's, extract their keys, build template functions and pass those along with a selector function to the base
ListViewimplementation.On a side note... how does this affect
RadListView? I gather we need the same (or a similar) API there.ginev commentedon Sep 29, 2016
@hdeshev RadListView suffers from the same illness regarding Angular 2.0 templates. We had to rewrite the logic that parses standard NS templates and binds them. Now, there is a callback that simply returns a ready
Viewfor an item. This is something similar to the suggestion done by @hamorphis above but without passing an index or data item as an argument:We can build on-top of that to implement the Template Selector functionality.
ginev commentedon Sep 29, 2016
Missed to point out that we're also using the
itemLoadingevent to perform the binding:lock commentedon Aug 28, 2019
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.