Hello,
Will the problem described [here](https://github.com/NativeScript/nativescript-angular/issues/377#issuecomment-275272724) be fixed or is there a workaround that does not involve refreshing the whole list?
I am currently using a component selector inside the radlistview, and when the "switchcase" inside that component changes and causes the background/display of the view to change, the element becomes white and nothing is rendered.
Thank you.
6 Answers, 1 is accepted
Thanks for writing.
I have reviewed the related discussion and can confirm that we have a similar example in our Angular SDK that works as expected:
https://github.com/telerik/nativescript-ui-samples-angular/tree/release/sdkAngular/app/listview/selection-states
Since I also noticed that in the related discussion the standard ListView component is used, I would like to ask you whether you are using ListView or RadListView? Does the above example help you implement your scenario or you need a different approach?
Thanks!
Regards,
Deyan
Progress Telerik

Hello Deyan,
The scenario in the example does not work for me. I am not trying to select items.
This is what I have
<
GridLayout
>
<
RadListView
backgroundColor
=
"transparent"
(itemLoading)="onItemLoading($event)" [items]="allCards">
<
ng-template
tkListItemTemplate
let-item
=
"item"
let-index
=
"index"
>
<
StackLayout
>
<
Label
*
ngIf
=
"item.sectionTitle"
class
=
"section-title"
[text]="item.sectionTitle"></
Label
>
<
StackLayout
class
=
"card"
>
<
ink-no-data
*
ngIf
=
"!defaultCard && loaded && index === 0"
[isCentered]=true [title]="'You have no default card!'" [description]="'Create or activate a card.'"></
ink-no-data
>
<
ink-card
[card]="item"
displayOptions
=
true
></
ink-card
>
</
StackLayout
>
</
StackLayout
>
</
ng-template
>
</
RadListView
>
</
GridLayout
>
<
StackLayout
orientation
=
"vertical"
class
=
"card-container"
[class.edit-display]="editDisplay && cardType !== 'image'">
<
GridLayout
[ngSwitch]="currentState"
class
=
"content"
>
<
NSImage
*
ngSwitchCase
=
"'qr'"
[src]="card.fullQRImageUrl"
stretch
=
"aspectFit"
(tap)="toggleQR()"></
NSImage
>
<
StackLayout
class
=
"template"
[class.collapsed]="currentState !== 'template'">
<
ng-template
inkCardTemplate></
ng-template
>
</
StackLayout
>
<
StackLayout
*
ngSwitchCase
=
"'image'"
class
=
"upload"
>
<
NSImage
src
=
"{{card.fullMediaUrl}}"
stretch
=
"fill"
height
=
"100%"
></
NSImage
>
</
StackLayout
>
<
DockLayout
class
=
"overlay"
stretchLastChild
=
false
(tap)="currentState === 'qr' ? toggleOptions() : ''">
<
StackLayout
dock
=
"top"
>
<
Button
*
ngIf
=
"(currentState === 'template' || currentState === 'image') && displayOptions"
class
=
"icon more-options rotate"
[text]="'\ue802'" (tap)="toggleOptions()"></
Button
>
<
Button
*
ngIf
=
"currentState !== 'template' && currentState !== 'image'"
class
=
"icon more-options"
[text]="'\ue805'" (tap)="close()"></
Button
>
</
StackLayout
>
<
StackLayout
dock
=
"bottom"
>
<
Button
*
ngIf
=
"displayEditButton && currentState !== 'qr'"
class
=
"icon edit-button"
[text]="'\ue80c'" (tap)="editCard()"></
Button
>
</
StackLayout
>
</
DockLayout
>
<
DockLayout
*
ngSwitchCase
=
"'options'"
class
=
"options"
stretchLastChild
=
false
>
<
GridLayout
rows
=
"auto"
dock
=
"top"
>
<
FlexboxLayout
class
=
"header"
flexDirection
=
"column"
>
<
Label
flexGrow
=
"1"
text
=
"{{card.name || 'No Name'}}"
fontSize
=
"16"
></
Label
>
<
Label
flexGrow
=
"1"
text
=
"created on {{card.createdDate | date:'longDate'}}"
fontSize
=
"14"
></
Label
>
</
FlexboxLayout
>
<
StackLayout
class
=
"overlay overlay-options"
>
<
Button
class
=
"icon more-options"
[text]="'\ue805'" (tap)="close()"></
Button
>
</
StackLayout
>
</
GridLayout
>
<
GridLayout
rows
=
"auto"
columns
=
"*, *"
dock
=
"bottom"
>
<
FlexboxLayout
class
=
"buttons-left"
flexDirection
=
"column"
flexGrow
=
"1"
>
<
Button
class
=
"option-button"
text
=
"Show QR Code"
(tap)="toggleQR()"
flexGrow
=
"1"
></
Button
>
<
Button
class
=
"option-button"
*
ngIf
=
"!card.isDefault"
text
=
"Make Default"
(tap)="makeDefault()"
flexGrow
=
"1"
></
Button
>
<
Button
class
=
"option-button"
text
=
"Edit Card"
(tap)="editCard()"
flexGrow
=
"1"
></
Button
>
</
FlexboxLayout
>
<
FlexboxLayout
class
=
"buttons-right"
flexDirection
=
"column"
col
=
"1"
flexGrow
=
"1"
>
<
Button
class
=
"option-button"
text
=
"Copy Url"
(tap)="copyURL()"
flexGrow
=
"1"
></
Button
>
<
Button
class
=
"option-button"
*
ngIf
=
"!card.isActive"
text
=
"Activate"
(tap)="activate()"
flexGrow
=
"1"
></
Button
>
<
Button
class
=
"option-button"
*
ngIf
=
"card.isActive && !card.isDefault"
text
=
"Deactivate"
(tap)="deactivate()"
flexGrow
=
"1"
></
Button
>
<
Button
class
=
"option-button"
text
=
"Delete"
(tap)="delete()"
flexGrow
=
"1"
></
Button
>
</
FlexboxLayout
>
</
GridLayout
>
</
DockLayout
>
</
GridLayout
>
</
StackLayout
>

I forgot to include in my reply that the screenshots are from a working scenario where I used ScrollView instead.
But I would like to use RadListView to make use of its functionality of loading only visible items on the viewport instead of the whole list.
Thank you.
Thanks for writing back.
Looking at your HTML code I presume the reason for the undesired behavior lies beneath the way RadListView works under iOS. We internally use the native iOS UICollectionView which does not automatically refresh when visual elements within the cell are added/removed - which the ngIf directive does here.
One possible approach I can think of is using the Multiple Templates support in RadListView which we have recently introduced:
http://docs.telerik.com/devtools/nativescript-ui/Controls/Angular/ListView/multiple-templates
Basically - you can define different views for different items.
Does this work for you?
Regards,
Deyan
Progress Telerik

We are facing the same issue - ven through we are using the Multiple templates approach and not *ngIf, the view is not refreshing when a new item is added to the observable array. Here is our html and component.
<
GridLayout
rows
=
"*"
class
=
"m-x-10"
>
<
RadListView
[items]="this.messagesForView" [itemTemplateSelector]="templateSelector">
<
ng-template
tkTemplateKey
=
"testPrint"
let-item
=
"item"
>
<
GridLayout
rows
=
"auto auto"
columns
=
"auto *"
>
<
Label
row
=
"0"
col
=
"0"
text
=
""
class
=
"fa p-10 m-y-5"
></
Label
>
<
Label
row
=
"0"
col
=
"1"
[text]="'Your test ' + item.testName + ' is ready for download at ' + item.testLink"
textWrap
=
"true"
></
Label
>
<
Label
row
=
"1"
col
=
"1"
text
=
"11:50"
horizontalAlignment
=
"right"
class
=
"m-r-10"
></
Label
>
</
GridLayout
>
</
ng-template
>
<
ng-template
tkTemplateKey
=
"otherMessage"
let-item
=
"item"
>
<
GridLayout
rows
=
"auto auto"
columns
=
"auto *"
>
<
Label
row
=
"0"
col
=
"0"
text
=
"ï…ƒ"
class
=
"fa p-t-4 m-y-5"
></
Label
>
<
Label
row
=
"0"
col
=
"1"
[text]="item.body"
textWrap
=
"true"
></
Label
>
<
Label
row
=
"1"
col
=
"1"
text
=
"13:10"
horizontalAlignment
=
"right"
class
=
"m-r-10"
></
Label
>
</
GridLayout
>
</
ng-template
>
</
RadListView
>
<!--For item delete -- pending implementation -->
<!-- <
GridLayout
*tkListItemSwipeTemplate
columns
=
"* *"
class
=
"listItemSwipeGridLayout"
height
=
"100%"
>
<
StackLayout
id
=
"mark-view"
class
=
"markViewStackLayout"
col
=
"0"
(tap)="onLeftSwipeClick($event)"
backgroundColor
=
"#FB7EA1"
height
=
"100%"
verticalAlignment
=
"center"
>
<
Label
text
=
"Undo"
horizontalAlignment
=
"center"
class
=
"question-swipe"
></
Label
>
</
StackLayout
>
<
StackLayout
id
=
"delete-view"
class
=
"deleteViewStackLayout"
col
=
"1"
(tap)="onRightSwipeClick($event)"
backgroundColor
=
"#FB7EA1"
height
=
"100%"
verticalAlignment
=
"center"
>
<
Label
text
=
"Delete"
horizontalAlignment
=
"center"
class
=
"question-swipe"
></
Label
>
</
StackLayout
>
</
GridLayout
> -->
</
GridLayout
>]
The component:
import { AfterContentInit, Component, OnInit, OnDestroy } from
"@angular/core"
;
import { NavigationExtras, Router } from
"@angular/router"
;
import { RouterExtensions } from
"nativescript-angular"
;
import { android } from
"application"
;
// THis is to import application for handleing back button.
import { DatePipe } from
'@angular/common'
;
// For showing time on message
import * as email from
"nativescript-email"
;
//for the email feature
import { Subscription } from
"rxjs/Rx"
;
import { Page } from
"ui/page"
;
import { Location } from
"@angular/common"
;
//import ui elements
import scrollViewModule = require(
"ui/scroll-view"
);
// import htmlViewModule = require("ui/html-view");
import { ListViewEventData, RadListView } from
"nativescript-telerik-ui/listview"
;
//This import is for rad list and event data on radList.
import { topmost } from
"ui/frame"
;
//To catch the rad list component as view.
import { View } from
"ui/core/view"
;
//To use a component as a View.
//to show dialog for modify Q
import { action } from
"ui/dialogs"
;
import { LoadingIndicator } from
"nativescript-loading-indicator"
;
import { isTablet } from
"../shared/device-constant/device.constant"
;
import { UserStatusService } from
"../services/userStatus.service"
;
import { FirebaseMessagingService } from
"../services/firebase-messaging.service"
;
// import { McqItem } from "../models/questionMCQ.model";
import { AndroidBAckButtonHandlerService } from
"../services/androidBackButtonHandler.service"
;
import { ObservableArray } from
"data/observable-array"
;
@Component({
moduleId: module.id,
selector:
"messaging"
,
styleUrls: [(isTablet ?
'../tablet.css'
:
'../phone.css'
)],
templateUrl:
"./messaging.component.html"
,
})
export class MessagingComponent implements OnInit, OnDestroy {
uid: string;
private backButtonHandler: Subscription;
public isTablet: boolean;
composeOptions: email.ComposeOptions;
public messagesForView: ObservableArray<any>;
private _templateSelector: (item: any, index: number, items: any) => string;
public messagesSubscriber: Subscription;
constructor(private router: Router,
private routerExtensions: RouterExtensions,
private location: Location,
private userStatusService: UserStatusService,
private firebaseMessagingService: FirebaseMessagingService,
private page: Page,
private androidBAckButtonHandlerService: AndroidBAckButtonHandlerService) {
}
public ngOnInit() {
this
.messagesForView =
new
ObservableArray();
this
._templateSelector =
this
.templateSelectorFunction;
this
.page.actionBarHidden =
true
;
this
.messagesSubscriber =
this
.firebaseMessagingService.messagesReceived.subscribe((currentMessages) => {
this
.messagesForView =
new
ObservableArray(currentMessages);
});
// this.firebaseMessagingService.getMessageFromFirebase();
if
(
this
.firebaseMessagingService.getMessages() !== undefined) {
this
.messagesForView =
new
ObservableArray(JSON.parse(
this
.firebaseMessagingService.getMessages()));
}
else
{
const welcomeMessage = {
type:
"otherMessage"
,
testName:
"Trial Test"
,
testLink:
"Trial Link"
,
title:
"Welcome"
,
body:
"Hello"
,
};
this
.messagesForView.push(welcomeMessage);
}
// this.loader.show(this.options);
//Subscribing android back button event emitter.
this
.backButtonHandler =
this
.androidBAckButtonHandlerService.detailTestBackHandler.subscribe((status) => {
console.log(
"Back button pressed on detail test component and the status is: "
+ JSON.stringify(status));
});
}
get templateSelector(): (item: any, index: number, items: any) => string {
return
this
._templateSelector;
}
set templateSelector(value: (item: any, index: number, items: any) => string) {
this
._templateSelector = value;
}
public templateSelectorFunction = (item: any, index: number, items: any) => {
return
item.type;
}
public ngOnDestroy() {
....
}
sendMail() {
...
}
}
Please tell us how we can get the list to refresh on its own (without needing a pull to refresh or navigating out and coming back).
Thanks
Can you please share which UI component are you using: RadListView or ListView? As the issue you are pointing is ListView related and this forum is related to RadListView cases.
In the meantime: you may want to check out the multiple templates functionality in RadListView:
http://docs.telerik.com/devtools/nativescript-ui/Controls/Angular/ListView/multiple-templates
It allows you to define a specific view depending on a given condition for the different items.
ListView supports multiple templates as well.
I hope this is helpful.
Regards,
Deyan
Progress Telerik