如何使用异步数据有条件地设置角度管道

时间:2017-10-19 23:44:39

标签: angular

我有一个非常简单的组件,可以制作一个漂亮的小仪表板卡,我可以将它重复用于多个数据。当我使用测试数据时,我的条件很好,因为它立即发送数据并选择正确的管道。但是,在真实的仪表板上,它需要API中的数据。返回数据,但由于这不再在ngOnInit中,我的条件不会触发。从我的服务中获取数据后,有人会知道我如何选择合适的条件吗?

组件:

import { Component, OnInit } from '@angular/core';
import {SecondsToMinutesPipe} from "../seconds-to-minutes.pipe";
import { DecimalPipe } from "@angular/common";

@Component({
  selector: 'app-dash-stat',
  inputs: [
    'icon', 'color', 'amount', 'description', 'time'
  ],
  templateUrl: './dash-stat.component.html',
  styleUrls: ['./dash-stat.component.css'],
})
export class DashStatComponent implements OnInit {

  private loading: boolean = true;
  private icon: string;
  private color: string = '#fff';
  private amount: any = 0;
  private description: string;
  private time: boolean = false;

  constructor(private timePipe: SecondsToMinutesPipe, private numberPipe: DecimalPipe) { }

  ngOnInit() {
      this.loading = false; //remove this and figure out 

      if(this.time){
        this.amount = this.timePipe.transform(this.amount);
      }
      else
      {
        this.amount = this.numberPipe.transform(this.amount, '1.0-0');
      }
  }

}

我从我的信息中心这样称呼它:

<div class="col-sm">
    <app-dash-stat icon="fa-tint" color="#eb1c2d" description="Litres Flown" amount="{{dashStats.volume}}"></app-dash-stat>
  </div>

  <div class="col-sm">
    <app-dash-stat icon="fa-clock-o" color="#fd6b00" description="Average Loading Time" amount="{{dashStats.filltime}}" time="true"></app-dash-stat>
  </div>

3 个答案:

答案 0 :(得分:1)

如果您想将数据从一个组件传递到另一个组件并进行此类数据更改,您需要创建一个可以订阅的可注入数据服务,该服务可以传递该值。这是我的数据服务的副本,为您提供一个想法:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { ReplaySubject } from 'rxjs/ReplaySubject';

@Injectable()
export class DataService {
    // for single non-async string data
    stringData: string; 


    // for complex async data; use setData/getData
    private dataItem: ReplaySubject<any> = new ReplaySubject<any>();

    public setData(data: any) {
        this.dataItem.next(data);
    };

    public getData(): Observable<any> {
        return this.dataItem.asObservable();
    };
}

在你的app.module.ts中导入它并将其添加到@NgModule提供者:

import { DataService } from '../app/Services/data.service';

 @NgModule({
...
     providers: [
         DataService
     ]
...

然后在两个组件中导入它:

import { DataService } from '../Services/data.service';

你可以在像这样的组件中使用它:

  

来源组件:

export class sourceComponent {
    myVariable: any;
    constructor(
        public dataService: DataService){

    // do something...
    }

    SomeFunction(): void {
    // do something...   
        this.dataService.setData(this.myVariable);
    }
}
  

目标组件:

import { Subscription } from "rxjs/Subscription";

// @component and stuff...
export class targetComponent {
    myValue: any;
    subscription: Subscription;

    constructor(
        public dataService: DataService) {     


        this.subscription = this.dataService.getData()
            .subscribe(
            data => {

                this.myValue = data;
                // do stuff maybe

                },
            error => {
                console.log(error);
            });
    }
}

然后,每当发生某些事情时,数据都应该更新。为了避免内存泄漏,请务必取消订阅目标组件,如下所示:

ngOnDestroy() {
    // unsubscribe to ensure no memory leaks
    this.subscription.unsubscribe();
}

答案 1 :(得分:0)

首先,如果您认为<app-dash-stat icon="fa-tint" color="#eb1c2d" description="Litres Flown" amount="{{dashStats.volume}}"></app-dash-stat>此语法会将数据传递给错误的<app-dash-stat>组件。代码在语法上是错误的。你不能简单地调用这样的属性。你应该用[ ]将它们括起来。 <app-dash-stat icon="fa-tint" [color]="#eb1c2d" [description]="Litres Flown" [amount]="dashStats.volume">并且您不能混合属性绑定和插值。 在您的类中,需要从父组件注入数据的变量,您应该使用@Input()注释。

@Input() private loading: boolean = true;
@Input() private icon: string;
@Input() private color: string = '#fff';
@Input() private amount: any = 0;
@Input() private description: string;
@Input() private time: boolean = false;

答案 2 :(得分:0)

我在想也许发射事件会起作用,但是ngOnChanges最终还是在做这个伎俩。

ngOnChanges(changes: SimpleChanges){

    this.loading = false; //remove this and figure out

    if(this.time){
      this.amount = this.timePipe.transform(changes.amount.currentValue);
    }
    else
    {
      this.amount = this.numberPipe.transform(changes.amount.currentValue, '1.0-0');
    }

  }