【问题标题】:Sharing JSON data from server between 2 components在 2 个组件之间共享来自服务器的 JSON 数据
【发布时间】:2018-10-03 14:42:07
【问题描述】:

我昨天发布了这个,但我今天更改了很多代码,我基本上重写了我的问题:

我有一个使用 TabView 模板的 NativeScript with Angular 应用程序和一个在选项卡上使用模式窗口的登录表单,这似乎工作正常 - 登录表单没有选项卡,登录后我被带到 TabView .

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

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

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

在 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 || {};
}    

}

然后在 reports.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;
} 

【问题讨论】:

    标签: angular nativescript angular2-nativescript


    【解决方案1】:

    你在哪个平台(ios/android)测试这个? ios 为列表视图或其父组件提供高度和宽度非常重要。否则,乍一看,您的代码对我来说很好。 您可以尝试其他一些方法来进一步调试

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

    2. 尝试像这样在加载时分配listview

    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;
    

    【讨论】:

    • 您好,感谢您的回复。我试过 3. 和 4. 没有成功。我想我需要像你说的那样刷新 RadListView。请您解释一下 1. 如何订阅 RadListView 的加载方法?我似乎在网上找不到太多关于它的信息。再次感谢。
    • 并在 .ts 文件中使用 onListLoaded(args) {this.listView = args.object;} 一旦你收到报告数据试试 this.listView.refresh();
    • 感谢您的快速回复。你知道我应该在 .ts 文件的顶部导入什么吗? listView 应该声明为什么类型?我目前有: import { ListViewEventData } from "nativescript-ui-listview";其次是私有listView:ListViewEventData;所以这一行 this.listView.refresh();正在产生错误:“ListViewEventData”类型上不存在属性“刷新”。谢谢。
    • 简单的解决方案是不定义listView的类型。将其保留为私有 listView;或
    • 从“nativescript-ui-listview”导入 { ListView };私有列表视图:列表视图;
    猜你喜欢
    • 2017-11-06
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 2017-04-15
    相关资源
    最近更新 更多