Заполнение представления radList для nativescript данными из Webservice - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть представление RadList, которое пытается заполнить данными из веб-службы.Данные, возвращаемые из сервиса, представлены в формате JSON.Поэтому я пытаюсь создать сервис, который я буду использовать для получения информации, передав соответствующий URL.Ниже приведены коды: -

интерфейс класса (cps-admin.interface.ts)

export class AddTenantInterface {
        tenant_id: string;
        tenant_names: string;
        tenant_contact: string;
        tenant_email: string;
        starting_date: string;
        rent_amount: string;
        initial_water_reading: string;
        water_unit_cost: string;
    }

службы (CPSAdminService.ts)

    import { Injectable } from "@angular/core";
    import { AddTenantInterface } from "../interfaces/cps-admin.interface";
    import { Observable } from "rxjs";
    import { HttpClient, HttpHeaders, HttpResponse } from "@angular/common/http";

    @Injectable()
    export class CPSAdminService {

        public _fetchTenantListUrl: string = "http://192.168.137.1/cps/fetchTenantsObj.php"; // fetch tenants list api url

        constructor(private _http: HttpClient) {}       

       fetchTenantsList()  {

            let headers = this.createRequestHeader();
            return this._http.get(this._fetchTenantListUrl, { headers: headers });

        }        

        private createRequestHeader() {
            // set headers here e.g.
            let headers = new HttpHeaders({
                "AuthKey": "my-key",
                "AuthToken": "my-token",
                "Content-Type": "application/json",
             });

            return headers;
        }  

    }

Вот здесьtenants-component.ts

import { Component, OnInit, ChangeDetectorRef, ViewChild, ChangeDetectionStrategy} from "@angular/core";
import { AddTenantInterface } from "./../../interfaces/cps-admin.interface";
import { CPSAdminService } from "./../../services/cps-admin.service";
import * as ApplicationSettings from "application-settings";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { RadListViewComponent } from "nativescript-ui-listview/angular";
import { ListViewLinearLayout, ListViewEventData, RadListView, LoadOnDemandListViewEventData } from "nativescript-ui-listview";
import { setTimeout } from "tns-core-modules/timer";
import { TextField } from "ui/text-field";

@Component({
    selector: "tenants-list",
    moduleId: module.id,
    templateUrl: "./tenants-list.component.html",
    styleUrls: ["./tenants-list.css"]
})

export class TenantListComponent implements OnInit {

   public rentItems: ObservableArray<AddTenantInterface>; 
    private _sourceDataItems: ObservableArray<AddTenantInterface>;
    private layout: ListViewLinearLayout;

    public searchPaymentsList: string;
    private _myFilteringFunc: (item: any) => any;
    @ViewChild("myListView") myListViewComponent: RadListViewComponent;

    constructor(private _cPSAdminService: CPSAdminService,  private _changeDetectionRef: ChangeDetectorRef) {}

    ngOnInit(): void {        

        this.layout = new ListViewLinearLayout();
        this.layout.scrollDirection = "Vertical";
        this.initDataItems();
        this._changeDetectionRef.detectChanges();
        this.rentItems = new ObservableArray<AddTenantInterface>();
        this.addMoreItemsFromSource(6);

    }

    get myFilteringFunc(): (item: any) => any {
        return this._myFilteringFunc;
    }

    set myFilteringFunc(value: (item: any) => any) {
        this._myFilteringFunc = value;
    }


   public onTextChanged(args) {
        let searchBar = <TextField>args.object;
        let listView = this.myListViewComponent.listView;

          this.myFilteringFunc = (item: AddTenantInterface) => {
              return item.tenant_names.includes(searchBar.text) || item.starting_date.includes(searchBar.text);
          };

        if (!listView.filteringFunction) {
            listView.filteringFunction = this.myFilteringFunc;
        } else {
            listView.filteringFunction = undefined;
        }

    } 

    get rentDataItems(): ObservableArray<AddTenantInterface> {
        return this.rentItems;
    }

    public addMoreItemsFromSource(chunkSize: number) {
        let newItems = this._sourceDataItems.splice(0, chunkSize);
        this.rentDataItems.push(newItems);
    }


    public onLoadMoreItemsRequested(args: LoadOnDemandListViewEventData) {
        const that = new WeakRef(this);
        if (this._sourceDataItems.length > 0) {
            setTimeout(function () {
                const listView: RadListView = args.object;
                that.get().addMoreItemsFromSource(2);
                listView.notifyLoadOnDemandFinished();
            }, 1000);
        } else {
            args.returnValue = false;
        }
    }
// ===== **PROBLEM IS HERE**
    private initDataItems() {
        this._sourceDataItems = new ObservableArray(this._cPSAdminService.fetchTenantsList()); 
    }

}

Обратите внимание, где я отметил "ПРОБЛЕМА ЗДЕСЬ", Вот клип с изображением ошибки У меня просто нет проблем.Когда я помещаю «any» в качестве метода, возвращаемого в fetchTenantsList (), например, fetchTenantsList (): any, ошибка исчезает, но в списке ничего не отображается.И когда я жестко кодирую данные там, как показано ниже, это работает;

    tenantData: AddTenantInterface[] =     [
    {
        "tenant_id":"542948",
        "tenant_names":"Jane Doe",
        "tenant_contact":"0787916686",
        "tenant_email":"jane.doe@ymail.com",
        "starting_date":"2004-08-09",
        "rent_amount":"850000",
        "initial_water_reading":"100",
        "water_unit_cost":"250"
    },
    {
        "tenant_id":"575550",
        "tenant_names":"Emily Clarke",
        "tenant_contact":"07752654868",
        "tenant_email":"emily.clarke@gmail.com",
        "starting_date":"2007-07-04",
        "rent_amount":"700000",
        "initial_water_reading":"400",
        "water_unit_cost":"250"
    },
    {
        "tenant_id":"422031",
        "tenant_names":"John Doe",
        "tenant_contact":"0772485364",
        "tenant_email":"john.doe@ymail.com",
        "starting_date":"2008-12-14",
        "rent_amount":"700000",
        "initial_water_reading":"120",
        "water_unit_cost":"250"
    }
];
fetchTenantsList(): AddTenantInterface[] {
  return this.tenantData;
}

Вот мой HTML-компонент:

<GridLayout class="page page-content custom_font_family m-5" rows="50, *">      


    <StackLayout class="input-field" row="0">
        <TextField 
                   hint="search..." 
                   [(ngModel)]='searchPaymentsList' 
                   secure="false"
                   returnKeyType="done" 
                   (textChange)="onTextChanged($event)"
                   autocorrect="false"
                   autocapitalizationType="allCharacters"
                   focus="onFocus"
                   blur="onBlur"
                   class="input input-border" 
                   color="navy" 
                   textFieldHintColor="#bfbfbf"></TextField>
    </StackLayout>

    <GridLayout tkExampleTitle tkToggleNavButton row="1"  rows="*">

        <RadListView [items]="rentDataItems" loadOnDemandMode="Manual" (loadMoreDataRequested)="onLoadMoreItemsRequested($event)" [filteringFunction]="myFilteringFunc" #myListView row="0">
            <ng-template tkListItemTemplate let-item="item" let-i="index" let-odd="odd" let-even="even">

             <StackLayout [class.odd]="odd" [class.even]="even"  class="list-group-item p-y-10 m-y-2 t-17 p-x-5">

                  <Label [text]='item.starting_date | date: "d-M-y"'></Label>
                  <Label [text]='item.tenant_id + ". "'></Label>
                  <Label [text]='item.tenant_names'></Label>
                  <Label [text]='item.tenant_contact'></Label>
                  <Label [text]='item.tenant_email'></Label>
                  <Label [text]='item.rent_amount | currency:"UG ":"Ug. ": "3.1-1"'></Label>

                </StackLayout>

                <!--</GridLayout>-->
            </ng-template>
            <ng-template tkListViewHeader>

                <GridLayout class="header" rows="*" columns="30, auto, auto, auto, auto, auto">

                  <Label row="0" col="0" text='Date'></Label>
                  <Label row="0" col="1" text='No '></Label>
                  <Label row="0" col="2" text='Names'></Label>
                  <Label row="0" col="3" text='Contact'></Label>
                  <Label row="0" col="4" text='Email'></Label>
                  <Label row="0" col="5" text='Rent'></Label>

                </GridLayout>

            </ng-template>


            <ListViewLinearLayout *tkIfIOS tkListViewLayout itemHeight="120"></ListViewLinearLayout>

            <div *tkIfIOS>
                <GridLayout *tkListLoadOnDemandTemplate class="loadOnDemandItemGridLayout">
                    <Label text="Load More" horizontalAlignment="center" verticalAlignment="center"></Label>
                </GridLayout>
            </div>

        </RadListView>
    </GridLayout>

</GridLayout>

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Хорошо, мой плохой.Я должен был удалить this.addMoreItemsFromSource (6) из ngOnInit () и поместить его в подписку.Вот решение.

import { Component, OnInit, ChangeDetectorRef, ViewChild, ChangeDetectionStrategy} from "@angular/core";
import { AddTenantInterface } from "./../../interfaces/cps-admin.interface";
import { CPSAdminService } from "./../../services/cps-admin.service";
import * as ApplicationSettings from "application-settings";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { RadListViewComponent } from "nativescript-ui-listview/angular";
import { ListViewLinearLayout, ListViewEventData, RadListView, LoadOnDemandListViewEventData } from "nativescript-ui-listview";
import { setTimeout } from "tns-core-modules/timer";
import { TextField } from "ui/text-field";

@Component({
    selector: "tenants-list",
    moduleId: module.id,
    templateUrl: "./tenants-list.component.html",
    styleUrls: ["./tenants-list.css"]
})

export class TenantListComponent implements OnInit {

   public rentItems: ObservableArray<AddTenantInterface>; 
    private _sourceDataItems: ObservableArray<AddTenantInterface>;
    private layout: ListViewLinearLayout;

    public searchPaymentsList: string;
    private _myFilteringFunc: (item: any) => any;
    @ViewChild("myListView") myListViewComponent: RadListViewComponent;

    constructor(private _cPSAdminService: CPSAdminService,  private _changeDetectionRef: ChangeDetectorRef) {}

    ngOnInit(): void {        

        this.layout = new ListViewLinearLayout();
        this.layout.scrollDirection = "Vertical";
        this.initDataItems();
        this._changeDetectionRef.detectChanges();
        this.rentItems = new ObservableArray<AddTenantInterface>();
        //this.addMoreItemsFromSource(6); // remove this and put it inthe initDataItems method

    }

    get myFilteringFunc(): (item: any) => any {
        return this._myFilteringFunc;
    }

    set myFilteringFunc(value: (item: any) => any) {
        this._myFilteringFunc = value;
    }


   public onTextChanged(args) {
        let searchBar = <TextField>args.object;
        let listView = this.myListViewComponent.listView;

          this.myFilteringFunc = (item: AddTenantInterface) => {
              return item.tenant_names.includes(searchBar.text) || item.starting_date.includes(searchBar.text);
          };

        if (!listView.filteringFunction) {
            listView.filteringFunction = this.myFilteringFunc;
        } else {
            listView.filteringFunction = undefined;
        }

    } 

    get rentDataItems(): ObservableArray<AddTenantInterface> {
        return this.rentItems;
    }

    public addMoreItemsFromSource(chunkSize: number) {
        let newItems = this._sourceDataItems.splice(0, chunkSize);
        this.rentDataItems.push(newItems);
    }


    public onLoadMoreItemsRequested(args: LoadOnDemandListViewEventData) {
        const that = new WeakRef(this);
        if (this._sourceDataItems.length > 0) {
            setTimeout(function () {
                const listView: RadListView = args.object;
                that.get().addMoreItemsFromSource(2);
                listView.notifyLoadOnDemandFinished();
            }, 1000);
        } else {
            args.returnValue = false;
        }
    }
    public initDataItems() {
        //this._sourceDataItems = new ObservableArray(this._cPSAdminService.fetchTenantsList());  

        this._cPSAdminService.fetchTenantsList()
        .subscribe( (result) => {
            this._sourceDataItems = new ObservableArray(result);
            this.addMoreItemsFromSource(6); // put it here
        },
        error => {
            console.log("Error: ", error);
        });
    }

}

Спасибо @ Manoj

0 голосов
/ 22 сентября 2018

this._cPSAdminService.fetchTenantsList ()

Возвращает Observable, который отправляет результат с сервера после завершения запроса.Вы не можете просто передать его в Observable Array.

Это должно быть что-то вроде этого,

this._cPSAdminService.fetchTenantsList()
      .subscribe((result) => {
           this._sourceDataItems = new ObservableArray(result);
      });
...