RadListView iOS item does not refresh

7 posts, 0 answers
  1. Ericky
    Ericky avatar
    49 posts
    Member since:
    Jun 2017

    Posted 31 Jul Link to this post

    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.

  2. Deyan
    Admin
    Deyan avatar
    2147 posts

    Posted 01 Aug Link to this post

    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.
  3. Ericky
    Ericky avatar
    49 posts
    Member since:
    Jun 2017

    Posted 01 Aug in reply to Deyan Link to this post

    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>
  4. Ericky
    Ericky avatar
    49 posts
    Member since:
    Jun 2017

    Posted 01 Aug Link to this post

    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.

  5. Deyan
    Admin
    Deyan avatar
    2147 posts

    Posted 03 Aug Link to this post

    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.
  6. Anurag
    Anurag avatar
    27 posts
    Member since:
    Apr 2016

    Posted 12 Sep Link to this post

    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

     

     

  7. Deyan
    Admin
    Deyan avatar
    2147 posts

    Posted 14 Sep Link to this post

    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.
Back to Top