在2个组件之间共享来自服务器的JSON数据

时间:2018-10-03 14:42:07

标签: angular nativescript angular2-nativescript

我昨天发布了这篇文章,但是今天我已经更改了很多代码,基本上我已经重写了我的问题:

我有一个使用TabView模板的带有Angular的NativeScript应用程序和一个使用表单上方的模态窗口的登录表单,这似乎可以正常工作-登录表单没有标签,并且登录后我进入了TabView

成功登录后,我想在选项卡式组件中调用方法,并使用已登录用户的特定内容更新各自的模板。

例如,其中之一是用户报告列表。

我试图通过从login.component.ts中的成功处理程序调用服务,然后在reports.component.ts中访问该服务,来从我们的服务器获取用户报告列表,并在reports.component.html中显示该列表。 / p>

在login.component.ts中,我位于顶部

    ...
import { User } from "../shared/user/user.model";
import { UserService } from "../shared/user/user.service";
import { ReportsComponent } from "../reports/reports.component";
import { UpdateService } from "../shared/update.service";
...

...
@Component({
    selector: 'login',
    moduleId: module.id,    
    providers: [UserService, ReportsComponent, ReportService, UpdateService ],
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.css']
})
...

在构造函数中,我有

private userService: UserService,
private repts: ReportsComponent,
private reportService: ReportService, 
private updateService: UpdateService,

那我有

public login() {

   this.userService.login(this.user)
   .subscribe(
        (data) => {              
            //console.log("login data in component = "+JSON.stringify(data));  


            if (data.authenticated==false) {
                ApplicationSettings.setBoolean("authenticated", false);
                alert("Unfortunately we could not log you in: "+data.message);
            } else if (data.authenticated==true) {
                ApplicationSettings.setBoolean("authenticated", true);
                ApplicationSettings.setString("token", data.token);

                console.log("authenticated="+ApplicationSettings.getBoolean("authenticated"));
                console.log("Login success! token="+data.token);

                console.log("calling updateReports from update.service.ts");

                this.updateReports();       

                //this.expense.populate_reports(this.expense); 
                //this.expense.populate_categories(this.expense); 

                this.modalDialogParams.closeCallback(() => console.log('Login modal closed'));

            }

        },
        (error) => alert("Unfortunately we could not log you in.")
   );        
}    
public updateReports() {
    this.updateService.getReports()
    .subscribe(
        (data) => {              
            //console.log("report data in login component = "+JSON.stringify(data));  
        },
        (error) => alert("Problems...")
   );         
}

在我拥有的update.service.ts中

@Injectable()
export class UpdateService {

private _expenses: ObservableArray<Expense>;

private reportDataSource = new Subject<string>(); // Source
reportData$ = this.reportDataSource.asObservable(); // Stream

constructor(private http: Http) { }


getReports() {
    console.log("in updateService getReports");

    let url = Config.apiUrl + "ns_get_reports.php";
    //console.log(url);
    return this.http.get(
        url,
        { headers: this.getCommonHeaders() }
    ).pipe(
        map(this.extractData),
        tap(data => {
            //alert("oi");
            this.reportDataSource.next(data);
            //console.log("reports listing in update service = "+JSON.stringify(data));
        }),
        catchError(this.handleErrors)
    );
}       
getCommonHeaders() {
    let headers = new Headers();
    let token=ApplicationSettings.getString("token");        
    headers.append("Content-Type", "application/json");
    headers.append("token", token);
    return headers;
}
handleErrors(error: Response) {
    console.log(JSON.stringify(error.json()));
    return Observable.throw(error);
}
private extractData(res: Response) {
    let body = res.json();
    return body || {};
}    

}

然后在我拥有的report.component.ts中

export class ReportsComponent implements OnInit {

//private report: Report;
private _reports: ObservableArray<Report>;
private _expenses: ObservableArray<Expense>;
header: string;
report_status: Array<String>;

subscription: Subscription;

constructor(private router: Router, 
    private reportService: ReportService, 
    private expenseService: ExpenseService,
    private _changeDetectionRef: ChangeDetectorRef, 
    private updateService: UpdateService) {

    this._reports = new ObservableArray<Report>();
    this.subscription = updateService.reportData$.subscribe(
        (res) => {
            console.log("reports listing in reports component = "+JSON.stringify(res));

            let data=JSON.parse(JSON.stringify(res));

            if (data["reports"]=="No Reports") {                 
                // No reports to show
            } else {  
                var status_text;
                var status_class;
                for (let i = 0; i < data.reportid.length; i++) {
                    var status_codes=this.displayReportStatus(data.report_status[i]);
                    status_text=status_codes[0];
                    status_class=status_codes[1];

                    this._reports.push(new Report(data.reportid[i], data.report_name[i], data.report_status[i], data.report_value[i], status_text, status_class, data.report_justification));
                }
                this._changeDetectionRef.markForCheck();
                if (!this._changeDetectionRef['destroyed']) {
                    this._changeDetectionRef.detectChanges();
                }

            }

        }
    );
}
public get reports(): ObservableArray<Report> {
    return this._reports;
} 

console.log("reports listing in reports component = "+JSON.stringify(data));

正在输出报告数据没问题,因此服务正在返回正确的数据。

但是,模板未显示格式化的报告列表。它是空白的。模板如下:

   <!--
    <RadListView [items]="reports" (itemTap)="onReportItemTap($event)" >
    //-->
    <RadListView [items]="reports" >
        <ng-template tkListItemTemplate let-item="item">
            <StackLayout class="itemTemplateStackLayout" orientation="vertical">

                    <StackLayout class="reportStackLayout" orientation="vertical">

                        <Label class="labelName blue_text bold_text list-group-item" [nsRouterLink]="['../report', item.reportid]" [text]="item.report_name"></Label>


                        <GridLayout class="reportDetailsGridLayout" columns="*, *">
                            <Label row="0" col="0" horizontalAlignment="left" [class]="item.status_class" class="labelStatus"  [text]="item.status_text" textWrap="true"></Label>
                            <Label row="0" col="1" horizontalAlignment="right" class="labelValue green_text bold_text" [text]="item.report_value" textWrap="true"></Label>
                        </GridLayout>

                    </StackLayout>

            </StackLayout>
        </ng-template>         
    </RadListView>
</GridLayout>

任何想法我在做什么错了。

希望我已经做了充分的解释-如果需要进一步澄清,请告诉我。

谢谢。

编辑:10月9日。

这是现在的reports.component.ts。仍然没有更新视图。

import { Component, ChangeDetectorRef, OnInit } from "@angular/core";

import { ReportComponent } from "./report.component";
import { Report } from "../shared/report/report.model";
import { Expense } from "../shared/expense/expense.model";
import { ReportService } from "../shared/report/report.service";
import { ExpenseService } from "../shared/expense/expense.service";
import { UpdateService } from "../shared/update.service";
import { Subject, Subscription } from 'rxjs';
import { ActivatedRoute, Router } from "@angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router"; 
import { Page } from "tns-core-modules/ui/page";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { ListViewEventData } from "nativescript-ui-listview";
import { RadListView } from "nativescript-ui-listview";


import { RouterExtensions } from "nativescript-angular/router";
import * as ApplicationSettings from "application-settings";
import {getBoolean, setBoolean, getNumber, setNumber, getString, setString, hasKey, remove, clear} from "tns-core-modules/application-settings";
import { Injectable } from "@angular/core";

declare var module: {
    id: string;
 }
@Component({
selector: "Reports",
moduleId: module.id,
providers: [ReportService, ExpenseService, UpdateService],
templateUrl: "./reports.component.html",
styleUrls: ["./reports.component.css"]
})


export class ReportsComponent implements OnInit {

//private report: Report;
private _reports: ObservableArray<Report>;
private _tempreports: ObservableArray<Report>;
private _expenses: ObservableArray<Expense>;
header: string;
report_status: Array<String>;
isLoading = true;
foo: string;

private listView: RadListView;

subscription: Subscription;

constructor(private router: Router, 
    private route: ActivatedRoute,
    private reportService: ReportService, 
    private expenseService: ExpenseService,
    private _changeDetectionRef: ChangeDetectorRef, 
    private updateService: UpdateService) {

        this.subscription = this.updateService.reportData$.subscribe(
            (res) => {
                console.log("isLoading="+this.isLoading);
                console.log("reports listing in reports component = "+JSON.stringify(res));


                this._reports = new ObservableArray<Report>();
                this._tempreports = new ObservableArray<Report>();

                let data=JSON.parse(JSON.stringify(res));

                if (data["reports"]=="No Reports") {                 
                    // No reports to show
                } else {  
                    var status_text;
                    var status_class;
                    for (let i = 0; i < data.reportid.length; i++) {
                        var status_codes=this.displayReportStatus(data.report_status[i]);
                        status_text=status_codes[0];
                        status_class=status_codes[1];

                        this._tempreports.push(new Report(data.reportid[i], data.report_name[i], data.report_status[i], data.report_value[i], status_text, status_class, data.report_justification));
                    }
                    this._reports = this._tempreports;
                    this._changeDetectionRef.markForCheck();
                    if (!this._changeDetectionRef['destroyed']) {
                        this._changeDetectionRef.detectChanges();
                    }

                    this.isLoading=false;
                    //this.listView.refresh();                      
                    console.log("isLoading="+this.isLoading);   

                }

            }
        );

}
onListLoaded(args) {
    console.log("In onListLoaded");
    this.listView = args.object;
    this.listView.refresh();     
}

public get reports(): ObservableArray<Report> {
    //console.log("Where are the focking reports");
    return this._reports;
} 

1 个答案:

答案 0 :(得分:0)

您正在测试哪个平台(ios / android)? 对于ios提供高度和宽度到列表视图或其父组件非常重要。否则,乍一看,您的代码对我来说看起来不错。 您还可以尝试其他几件事进行进一步调试

  1. 订阅(已加载)RadListView的方法。

  2. 尝试在这样加载的状态下分配列表视图

onListLoaded(args){this.listView = args.object;}

,并在获得报告数据后通过this.listview.refresh()刷新列表视图。 3.首先有一个activityIndi​​cator并隐藏列表。收到报告后隐藏指示器,使丢失的内容可见。

<ActivityIndicator [busy]="isLoading" [visibility]="isLoading ? 'visible' : 'collapse'" row="2" horizontalAlignment="center"></ActivityIndicator>

4。将数据推送到临时数组,一旦所有项目都被使用,请将该临时数组分配给报表。

_tempreports.push(new Report(data.reportid[i], data.report_name[i], data.report_status[i], data.report_value[i], status_text, status_class, data.report_justification));
this._reports = _tempreports;