点击操作后刷新 NativeScript (Angular) 标签文本(更新标签)

Refresh NativeScript (Angular) Labels text after tap action (updating label)

我在 NativeScript 应用程序中有一个代表状态的标签列表。我有一种方法可以在点击后更改每个标签的状态。在我点击标签后,它应该更改状态值(数字)并在点击后立即在屏幕上显示新值。

我所做的部分工作。我必须点击它两次才能看到标签发生变化,或者点击一次并拉动以刷新才能看到标签发生变化。服务中的更新也在点击后按预期工作。对如何正确实施此行为有任何想法吗?

观看次数: parent 分量:

<StackLayout *ngFor="let phase of (training$ | async)?.phases; let i = index">
    <StackLayout *ngIf="(training$ | async)?.phases">
        <StackLayout>
            <ns-phase-item [phase]="phase" [training$]="training$" [i]="i"></ns-phase-item>
        </StackLayout>
    </StackLayout>
</StackLayout> 

第一个 child (ns-phase-item):

<StackLayout>
    <Label [text]="phase.phaseTitle" [textWrap]="true" class="title-wrap"></Label>
    <StackLayout *ngFor="let unit of (training$ | async).phases[i].units">
         <ns-unit-item [unit]="unit" class="unit"></ns-unit-item>
    </StackLayout>
</StackLayout>

Child 第一个 child 视图 (ns-unit-item)(我调用更新方法的地方):

<StackLayout [ngClass]="{ 'unit-completed': unit.status === 1, 'unit-not-completed': unit.status !== 1 }">
 <GridLayout columns="4*, *" rows="auto">
    <FlexboxLayout col="0" flexDirection="row" (tap)="onView(unit._id)">
        <Label [text]="(unit.date | date: 'd. MMM') + ' - ' + unit.unitTitle"></Label>
        <Label *ngIf="unit.duration || unit.distance" text=" ("></Label>
        <Label *ngIf="unit.duration" [text]="' ' + unit.duration + ' min'"></Label>
        <Label *ngIf="unit.duration && unit.distance" text=" / "></Label>
        <Label *ngIf="unit.distance" [text]="unit.distance + ' km'"></Label>
        <Label *ngIf="unit.duration || unit.distance" text=")"></Label>
        <Label *ngIf="unit$" [text]="(unit$ | async).status"></Label>
    </FlexboxLayout>
    <StackLayout col="1">
        <StackLayout *ngIf="(unit$ | async).status == 1">
  // HERE I CALL UPDATE - it should change the value and icon after tap
            <Image src="res://check" height="20" stretch="aspectFit" (tap)="onStatusUpdate(0)"></Image>
        </StackLayout>
        <StackLayout *ngIf="(unit$ | async).status == 0">
            <Image src="res://checkgray" height="20" stretch="aspectFit" (tap)="onStatusUpdate(1)"></Image>
        </StackLayout>
    </StackLayout>
  </GridLayout>
</StackLayout>

Child 第一个 child 控制器(ns-unit-item 组件)

private _unit: BehaviorSubject<Unit> = new BehaviorSubject<Unit>(null)


getUnitObservable(): Observable<Unit> {
    return this._unit.asObservable()
}

getUnitValue(): Unit {
    return this._unit.getValue()
}

unitChanged(unit: Unit) {
    this._unit.next(unit)
}

ngOnInit(): void {
    this.unitChanged(this.unit)
    this.unit = this.getUnitValue()
    this.unit$ = this.getUnitObservable()
}

onStatusUpdate(status: number) {
    this.trainingService.updateTrainingUnitStatus(this.unit._id, status).subscribe((unit) => {
        this.unitChanged(unit)
        this.unit$ = this.getUnitObservable()
    })
}

我调用的服务API

updateTrainingUnitStatus(id: string, status: number) {
    return this.http.post<Unit>(`${this.API_URL_UNITS}/${id}/status`, { status: status })
}

我使用 RxJS BehaviorSubject 来完成它。我已经简化了解决方案,并使用 BehaviorSubject 只有数字而不是完整的对象。

在服务中:

public unitStatus: BehaviorSubject<Number> = new BehaviorSubject<Number>(0)

在组件中调用 API 进行更新之前,我在 BehaviorSubject

上调用 next
onStatusUpdate(status: number) {
    console.log(status)
    this.trainingService.unitStatus.next(status)
    this.subscription = this.trainingService
        .updateTrainingUnitStatus(this.unitId, status)
        .pipe(tap((data) => console.log(data.status)))
        .subscribe(() => {
            this.status$ = this.trainingService.unitStatus.asObservable()
            this.status = this.trainingService.unitStatus.getValue()
            console.log(this.status)
        })
}

在视图中,我使用“状态”属性,它在点击按钮后发生变化(并且与来自数据库的持久数据内联)

<FlexboxLayout margin="0" padding="0">
            <Button
                *ngIf="status === 0"
                text="MARK AS DONE"
                (tap)="onStatusUpdate(1)"
                class="-rounded -primary"
            ></Button>
            <Button
                *ngIf="status === 1"
                text="MARK AS NOT DONE"
                (tap)="onStatusUpdate(0)"
                class="-rounded -primary"
            ></Button>
        </FlexboxLayout>