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

RadListView iOS item does not refresh

6 Answers 460 Views
ListView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Ericky
Top achievements
Rank 1
Ericky asked on 01 Aug 2017, 04:16 AM

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

Sort by
0
Deyan
Telerik team
answered on 01 Aug 2017, 07:50 AM
Hello,

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
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
0
Ericky
Top achievements
Rank 1
answered on 01 Aug 2017, 12:09 PM

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>
0
Ericky
Top achievements
Rank 1
answered on 01 Aug 2017, 12:10 PM

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.

0
Deyan
Telerik team
answered on 03 Aug 2017, 02:09 PM
Hello,

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
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
0
Anurag
Top achievements
Rank 1
answered on 12 Sep 2017, 01:55 PM

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

 

 

0
Deyan
Telerik team
answered on 14 Sep 2017, 10:48 AM
Hello,

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
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
Tags
ListView
Asked by
Ericky
Top achievements
Rank 1
Answers by
Deyan
Telerik team
Ericky
Top achievements
Rank 1
Anurag
Top achievements
Rank 1
Share this question
or