使用来自 Web 服务的数据填充 nativescript radList 视图
Populating nativescript radList view with Data from Webservice
我有一个 RadList 视图,它试图用来自 Web 服务的数据填充。从服务 return 编辑的数据采用 JSON 格式。因此,我正在尝试创建一项服务,我将使用该服务通过传递相应的 URL 来获取信息。以下是代码:-
接口class (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;
}
}
这里是租户-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());
}
}
注意我标记的地方"PROBLEM IS HERE",Here is the error image clip
我只是不知道是什么问题。当我像这样将 "any" 作为方法 return 放在 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>
感谢任何帮助。
this._cPSAdminService.fetchTenantsList()
这将 return 一个 Observable,它在请求完成时从服务器发出结果。你不能简单地将它传递给 Observable Array。
一定是这样的,
this._cPSAdminService.fetchTenantsList()
.subscribe((result) => {
this._sourceDataItems = new ObservableArray(result);
});
好吧,我的错。我应该删除
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
我有一个 RadList 视图,它试图用来自 Web 服务的数据填充。从服务 return 编辑的数据采用 JSON 格式。因此,我正在尝试创建一项服务,我将使用该服务通过传递相应的 URL 来获取信息。以下是代码:-
接口class (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;
}
}
这里是租户-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());
}
}
注意我标记的地方"PROBLEM IS HERE",Here is the error image clip 我只是不知道是什么问题。当我像这样将 "any" 作为方法 return 放在 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>
感谢任何帮助。
this._cPSAdminService.fetchTenantsList()
这将 return 一个 Observable,它在请求完成时从服务器发出结果。你不能简单地将它传递给 Observable Array。
一定是这样的,
this._cPSAdminService.fetchTenantsList()
.subscribe((result) => {
this._sourceDataItems = new ObservableArray(result);
});
好吧,我的错。我应该删除 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