NativeScript如何动态更新视图?

问题描述 投票:-1回答:1

我是NativeScript应用程序开发的新手,我将尝试描述整个情况,希望您能再次帮助我找到解决方案。

[我开始将底部导航(带有4个选项卡:预测,新闻...)作为组件,以及侧面抽屉(具有5种不同的运动)。

[从侧面抽屉中,用户可以选择运动,因此整个视图的颜色会发生变化,例如,在选项卡预测中,我要显示所选运动的预测。

一切正常,不幸的是,带有所选预测的列表()不会更新,只有带有计数器的Label用于预测。我不知道实现这一目标的最佳方法是什么。

这是home.component.html,它在每个选项卡中显示信息:

<ActionBar [class]="sport_class">
    <NavigationButton ios:visibility="collapsed" icon="res://menu"
        (tap)="onDrawerButtonTap()"></NavigationButton>
    <ActionItem icon="res://menu" android:visibility="collapsed"
        (tap)="onDrawerButtonTap()" ios.position="left">
    </ActionItem>
    <Image [src]="logoSrc" class="logo"></Image>
</ActionBar>
<BottomNavigation selectedIndex="0">
    <TabStrip [class]="sport_class">
        <TabStripItem>
            <Label text="Predictions"></Label>
            <Image src="font://&#xf1e3;" class="fas t-36"></Image>
        </TabStripItem>
        <TabStripItem>
            <Label text="Bookmakers"></Label>
            <Image src="font://&#xf66f;" class="fas t-36"></Image>
        </TabStripItem>
        <TabStripItem>
            <Label text="Bonuses"></Label>
            <Image src="font://&#xf0a3;" class="fas t-36"></Image>
        </TabStripItem>
        <TabStripItem>
            <Label text="News"></Label>
            <Image src="font://&#xf518;" class="fas t-36"></Image>
        </TabStripItem>
    </TabStrip>

    <TabContentItem>
        <GridLayout>
            <Label [text]="'Predictions ' + sport_class + ', count: ' + predictions.length"></Label>
            <ns-predictions></ns-predictions>
        </GridLayout>
    </TabContentItem>
    <TabContentItem>
        <GridLayout>
            <ns-bookmakers></ns-bookmakers>
        </GridLayout>
    </TabContentItem>
    <TabContentItem>
        <GridLayout>
            <ns-bonuses></ns-bonuses>
        </GridLayout>
    </TabContentItem>
    <TabContentItem>
        <GridLayout>
            <ns-news></ns-news>
        </GridLayout>
    </TabContentItem>
</BottomNavigation>

这里是home.component.ts

import { Component, OnInit } from "@angular/core";
import { RadSideDrawer } from "nativescript-ui-sidedrawer";
import { ActivatedRoute } from '@angular/router';
import * as app from "tns-core-modules/application";
import { getString, setString } from "tns-core-modules/application-settings";
import { PredictionsService } from '../predictions/predictions.service';
import { Prediction } from '../predictions/predictions.model';

@Component({
    selector: "Home",
    moduleId: module.id,
    templateUrl: "./home.component.html",
    styleUrls: ["./home.component.css"]
})
export class HomeComponent implements OnInit {

    predictions: Prediction[];
    public isLoading = false;
    public listLoaded = false;
    public sport_class: string;
    private logoSrc: string;

    constructor(private predictionService: PredictionsService, private route: ActivatedRoute) {
        this.route.paramMap.subscribe(
            params => {
                this.sport_class = params.get('sport');
                this.logoSrc = getString('logo');
                this.loadPredictions();
            }
        )
    }

    ngOnInit(): void {
        this.isLoading = true;
        this.loadPredictions();
        this.isLoading = false;
        this.listLoaded = true;
    }

    private async loadPredictions() {

        let date = '2020-05-19';
        return this.predictionService.getItems(date, this.sport_class).subscribe((data: any[]) => {
            this.predictions = data;
        });

    }

    onDrawerButtonTap(): void {
        const sideDrawer = <RadSideDrawer>app.getRootView();
        sideDrawer.showDrawer();
    }
}

这里是predictions.component.ts:

import { Component, OnInit } from '@angular/core';
import { PredictionsService } from './predictions.service';
import { Prediction } from './predictions.model';
import {
    getBoolean,
    getNumber,
    getString,
} from "tns-core-modules/application-settings";

var utilityModule = require("utils/utils");

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

export class PredictionsComponent implements OnInit {

    predictions: Prediction[];
    public isLoading = false;
    public listLoaded = false;

    constructor(private predictionService: PredictionsService) { }

    ngOnInit(): void {
        this.isLoading = true;
        this.loadPredictions();
        this.isLoading = false;
        this.listLoaded = true;
    }

    private async loadPredictions() {

        let date = '2020-05-19';
        return this.predictionService.getItems(date, getString('sport')).subscribe((data: any[]) => {
            console.log('I am here');
            this.predictions = data;
        });

    }

}

app.component.ts

import { Component, OnInit } from "@angular/core";
import { NavigationEnd, Router } from "@angular/router";
import { RouterExtensions } from "nativescript-angular/router";
import { DrawerTransitionBase, RadSideDrawer, SlideInOnTopTransition } from "nativescript-ui-sidedrawer";
import { filter } from "rxjs/operators";
import { Store } from '@ngxs/store';
import * as app from "tns-core-modules/application";
import { getString, setString } from "tns-core-modules/application-settings";

@Component({
    selector: "ns-app",
    templateUrl: "app.component.html"
})

export class AppComponent implements OnInit {
    private _activatedUrl: string;
    private _sideDrawerTransition: DrawerTransitionBase;
    public sport_class: string;
    public logoSrc: string;

    constructor(private router: Router, private routerExtensions: RouterExtensions, private store: Store) {
        // Use the component constructor to inject services.
        this.setSport('tennis');
        this.logoSrc = getString('logo');
    }

    ngOnInit(): void {
        this._activatedUrl = "/predictions/tennis";
        this._sideDrawerTransition = new SlideInOnTopTransition();

        this.router.events
            .pipe(filter((event: any) => event instanceof NavigationEnd))
            .subscribe((event: NavigationEnd) => this._activatedUrl = event.urlAfterRedirects);
    }

    get sideDrawerTransition(): DrawerTransitionBase {
        return this._sideDrawerTransition;
    }

    onSportTap(sport: string) {
        this.setSport(sport);
        this.routerExtensions.navigate(['predictions/' + sport], {
            transition: {
                name: "fade"
            }
        });

        const sideDrawer = <RadSideDrawer>app.getRootView();
        sideDrawer.closeDrawer();
    }

    isComponentSelected(url: string): boolean {
        return this._activatedUrl === url;
    }

    onNavItemTap(navItemRoute: string): void {
        this.routerExtensions.navigate([navItemRoute], {
            transition: {
                name: "fade"
            }
        });

        const sideDrawer = <RadSideDrawer>app.getRootView();
        sideDrawer.closeDrawer();
    }

    setSport(sport: string) {
        this.sport_class = sport;
        setString("sport", sport);
        this.logoSrc = this.getLogoPath(getString('sport'));
        setString("logo", this.getLogoPath(sport));
    }

    getLogoPath(sport: string) {
        return  sport + '/logo.png';
    }
}
angular nativescript nativescript-angular
1个回答
0
投票

我看不到抽屉的实现,但是您没有将数据传递给NS-predictions组件,因此列表将永远不会更新,您需要对运动选择做出反应,然后加载当前运动的数据,然后将其传递给使用输入将数据存储到NS-predictions组件中,您也可以使用Ngxs之类的库将状态内部的信息集中起来,然后在您的NS-predictions组件中,您只需订阅该状态内的值即可获取更改https://www.ngxs.io/

这是一个示例,您如何使用诸如NGXS之类的状态管理库解决问题

  • 从抽屉发送对运动选择的操作,将运动或sportId作为参数传递this.store.dispatch(new SelectSport(sport))
  • 然后假设您的运动状态具有以下属性选定的运动体育等
  • 也是一个PredictionsState正在加载预测等等
  • [当分派SelectSport事件时,您可以在内部预测组件中侦听该事件,然后分派另一个操作,例如通过该选定运动的负荷预测,在您的预测状态内部,您可以调用该服务以加载预测并用您的预测更新您的状态
  • 最后,在预测组件内部,您需要选择ur预测状态的一部分,在这种情况下,predictions属性并将其传递给ur列表。

也许这是组织各州之间交流的更好方法,但这就是我刚刚想出的,希望对您有帮助。>

您可以找到有关如何做我在离开您的链接中描述的所有信息

© www.soinside.com 2019 - 2024. All rights reserved.