在Angular 8中使用服务过滤阵列

在Angular 8中使用服务过滤阵列,angular,typescript,Angular,Typescript,我只是尝试根据object的属性显示数组的当前项(而不是新添加的项)。阵列从服务到组件。我尝试了不同的方法,但当我在angular生命周期迷宫中尝试它们时,它不起作用 这是服务: private transactions: Transaction [] = [ new Transaction('Coles', 27.8, 'Groceries'), new Transaction('Translink', 20, 'Transportation'), ]; ge

我只是尝试根据object的属性显示数组的当前项(而不是新添加的项)。阵列从服务到组件。我尝试了不同的方法,但当我在angular生命周期迷宫中尝试它们时,它不起作用

这是服务:


  private transactions: Transaction [] = [
    new Transaction('Coles', 27.8, 'Groceries'),
    new Transaction('Translink', 20, 'Transportation'),
  ];


  getTransaction()  {
    return this.transactions.slice();
  }

  getGroceries(transactions: Transaction)  {
     for (item of this.transactions) {
       if (item.category === "groceries")
         this.groceries.push(item);
}
    }
这是一个组件:

export class TransactionsComponent implements OnInit, OnDestroy {
  transactions: Transaction[];
  groceriesList: Transaction[]; 
  private igChangeSub: Subscription

  constructor(private trService:TransactionsService) {}

  ngOnInit() {
    this.transactions = this.trService.getTransaction();
    this.igChangeSub = this.trService.transactionsChanged
      .subscribe(
        (transactions: Transaction[]) => {
          this.transactions = transactions; 
        }
      )   
      this.groceriesList = this.trService.getGroceries(transactions: Transaction[])  
    }


   onAddItem(form: NgForm) {
    const value = form.value;
    const newTransaction = new Transaction(value.name, value.amount, value.category)
    this.trService.addTransaction(newTransaction)
  }

  ngOnDestroy (): void {
    this.igChangeSub.unsubscribe();
  }


}
我也试过了

getGroceries() {
    for(let item of this.transactions) {
      let groceries = this.transactions.filter( a=>a.category === "Groceries")
      console.log(groceries)

   }
  }
我不确定是否必须在服务或组件上创建新阵列(没有一个有效)。任何帮助都将不胜感激,谢谢


下面是stackblitz:

首先,我建议您使用接口而不是类进行事务处理。原因是他们更容易合作。你不必对它们进行更新,你可以更宽松地处理它们。我想这是一个品味的问题,但在工作中,我们有一个规则,只有当你想让类做一些事情时,我们才使用类。我们想要作为接口的数据模型

不管怎样,这不是你真正想知道的。这里的问题是,您的事务可能没有获得新的引用。角度变化检测不会检测到您已更改阵列,也不会重新绘制该零件。我假设您在调试期间检查了数据是否符合预期

如果是这样的话,就应该这样做:

this.igChangeSub = this.trService.transactionsChanged
      .subscribe(
        (transactions: Transaction[]) => {
          this.transactions = [...transactions]; 
        }
      )   
      this.groceriesList = this.trService.getGroceries(transactions: Transaction[])  
    }
或者这个:

  onAddItem(form: NgForm) {
    const value = form.value;
    const newTransaction = new Transaction(value.name, value.amount, value.category)
    this.trService.addTransaction(newTransaction)
    this.transactions = [...this.trService.getTransaction()]
  }
这将创建一个新数组,它是一个新引用,然后This.transactions将获得一个新引用,该引用将触发更改检测


你没有把所有的东西都贴出来,所以我可能遗漏了一些东西。我不知道您是如何将trService.addTransaction与订阅连接起来的,因此可能也有问题。

首先,我建议您使用接口而不是类进行事务处理。原因是他们更容易合作。你不必对它们进行更新,你可以更宽松地处理它们。我想这是一个品味的问题,但在工作中,我们有一个规则,只有当你想让类做一些事情时,我们才使用类。我们想要作为接口的数据模型

不管怎样,这不是你真正想知道的。这里的问题是,您的事务可能没有获得新的引用。角度变化检测不会检测到您已更改阵列,也不会重新绘制该零件。我假设您在调试期间检查了数据是否符合预期

如果是这样的话,就应该这样做:

this.igChangeSub = this.trService.transactionsChanged
      .subscribe(
        (transactions: Transaction[]) => {
          this.transactions = [...transactions]; 
        }
      )   
      this.groceriesList = this.trService.getGroceries(transactions: Transaction[])  
    }
或者这个:

  onAddItem(form: NgForm) {
    const value = form.value;
    const newTransaction = new Transaction(value.name, value.amount, value.category)
    this.trService.addTransaction(newTransaction)
    this.transactions = [...this.trService.getTransaction()]
  }
这将创建一个新数组,它是一个新引用,然后This.transactions将获得一个新引用,该引用将触发更改检测


你没有把所有的东西都贴出来,所以我可能遗漏了一些东西。我不知道您是如何将trService.addTransaction与订阅连接起来的,因此可能也有问题。

下面是一个使用角度服务作为状态的示例。需要记住的是,您希望坚持将事务的所有更新都保存在一个中心位置(服务)的“假数据库”(或您想称之为假数据库的任何内容)

下面是一个Stackblitz演示:

通过使用
事件发射器
主题
可观察对象
,还有多种其他方法可以实现这一点。。。然而,如果您发现自己需要一个好的工具来管理状态,我建议您研究一下。但是,我会说,如果您发现自己在努力理解Angular生命周期挂钩和Angular的一般流程,那么现在使用像NgRx这样的状态机可能有点困难。但是,这无疑是美国国家管理的目标

服务

export class TransactionServiceService {
  private transactions: Transaction[];
  constructor() {
    this.transactions = [];
  }
  addTransaction(transaction: Transaction): Transaction[] {
    this.transactions.push(transaction);
    return this.transactions;
  }
  removeTransaction(transaction: Transaction): Transaction[] {
    return this.transactions.filter(t =>
      t.name !== transaction.name &&
      t.amount !== transaction.amount &&
      t.category !== transaction.category
    );
  }
  getTransactions(): Transaction[] {
    return this.transactions;
  }
  getTransactionsByCategory(category: string): Transaction[] {
    return this.transactions.filter( t => t.category === category);
  }
}
<button (click)="getItems()">Get All Items</button>
<button (click)="filterTransactions('Groceries')">Get Groceries</button>
<button (click)="filterTransactions('Transportation')">Get Transportation</button>
<div *ngFor="let transaction of transactions">{{transaction | json}}</div>
在服务中构建CRUD函数以管理事务状态后,您可以在任何组件中使用它:

export class TransactionsComponent implements OnInit, OnDestroy {
  transactions: Transaction[];
  groceriesList: Transaction[]; 
  private igChangeSub: Subscription

  constructor(private trService:TransactionsService) {}

  ngOnInit() {
    this.transactions = this.trService.getTransaction();
    this.igChangeSub = this.trService.transactionsChanged
      .subscribe(
        (transactions: Transaction[]) => {
          this.transactions = transactions; 
        }
      )   
      this.groceriesList = this.trService.getGroceries(transactions: Transaction[])  
    }


   onAddItem(form: NgForm) {
    const value = form.value;
    const newTransaction = new Transaction(value.name, value.amount, value.category)
    this.trService.addTransaction(newTransaction)
  }

  ngOnDestroy (): void {
    this.igChangeSub.unsubscribe();
  }


}
组件

import { Component } from '@angular/core';
import { TransactionServiceService } from './transaction-service.service';
import { Transaction } from './transaction';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  private readonly transactionService: TransactionServiceService;
  public transactions: Transaction[];
  constructor(transactionService: TransactionServiceService) {
    this.transactionService = transactionService;
    const transactions = [
      { name: 'Coles', amount: 27.8, category: 'Groceries' } as Transaction,
      { name: 'TransLink', amount: 20, category: 'Transportation' } as Transaction,
      { name: 'TransLink', amount: 25, category: 'Transportation' } as Transaction
    ];
    transactions.forEach(t => this.transactionService.addTransaction(t) );
  }
  getItems(): void {
    this.transactions = this.transactionService.getTransactions();
  }
  filterTransactions(category: string): void {
    this.transactions = this.transactionService.getTransactionsByCategory(category);
  }
}
模板

export class TransactionServiceService {
  private transactions: Transaction[];
  constructor() {
    this.transactions = [];
  }
  addTransaction(transaction: Transaction): Transaction[] {
    this.transactions.push(transaction);
    return this.transactions;
  }
  removeTransaction(transaction: Transaction): Transaction[] {
    return this.transactions.filter(t =>
      t.name !== transaction.name &&
      t.amount !== transaction.amount &&
      t.category !== transaction.category
    );
  }
  getTransactions(): Transaction[] {
    return this.transactions;
  }
  getTransactionsByCategory(category: string): Transaction[] {
    return this.transactions.filter( t => t.category === category);
  }
}
<button (click)="getItems()">Get All Items</button>
<button (click)="filterTransactions('Groceries')">Get Groceries</button>
<button (click)="filterTransactions('Transportation')">Get Transportation</button>
<div *ngFor="let transaction of transactions">{{transaction | json}}</div>
获取所有项目
买食品杂货
搭便车
{{transaction}json}

如果您试图获取最后一个事务,您可以轻松获取它,因为此方法使用
Array.push
。但是,我建议您在事务中添加一个标识符,以便更容易找到它们。

下面是一个使用角度服务进行状态查询的示例。需要记住的是,您希望坚持将事务的所有更新都保存在一个中心位置(服务)的“假数据库”(或您想称之为假数据库的任何内容)

下面是一个Stackblitz演示:

通过使用
事件发射器
主题
可观察对象
,还有多种其他方法可以实现这一点。。。然而,如果您发现自己需要一个好的工具来管理状态,我建议您研究一下。但是,我会说,如果您发现自己在努力理解Angular生命周期挂钩和Angular的一般流程,那么现在使用像NgRx这样的状态机可能有点困难。但是,这无疑是美国国家管理的目标

服务

export class TransactionServiceService {
  private transactions: Transaction[];
  constructor() {
    this.transactions = [];
  }
  addTransaction(transaction: Transaction): Transaction[] {
    this.transactions.push(transaction);
    return this.transactions;
  }
  removeTransaction(transaction: Transaction): Transaction[] {
    return this.transactions.filter(t =>
      t.name !== transaction.name &&
      t.amount !== transaction.amount &&
      t.category !== transaction.category
    );
  }
  getTransactions(): Transaction[] {
    return this.transactions;
  }
  getTransactionsByCategory(category: string): Transaction[] {
    return this.transactions.filter( t => t.category === category);
  }
}
<button (click)="getItems()">Get All Items</button>
<button (click)="filterTransactions('Groceries')">Get Groceries</button>
<button (click)="filterTransactions('Transportation')">Get Transportation</button>
<div *ngFor="let transaction of transactions">{{transaction | json}}</div>
在服务中构建CRUD函数以管理事务状态后,您可以在任何组件中使用它:

export class TransactionsComponent implements OnInit, OnDestroy {
  transactions: Transaction[];
  groceriesList: Transaction[]; 
  private igChangeSub: Subscription

  constructor(private trService:TransactionsService) {}

  ngOnInit() {
    this.transactions = this.trService.getTransaction();
    this.igChangeSub = this.trService.transactionsChanged
      .subscribe(
        (transactions: Transaction[]) => {
          this.transactions = transactions; 
        }
      )   
      this.groceriesList = this.trService.getGroceries(transactions: Transaction[])  
    }


   onAddItem(form: NgForm) {
    const value = form.value;
    const newTransaction = new Transaction(value.name, value.amount, value.category)
    this.trService.addTransaction(newTransaction)
  }

  ngOnDestroy (): void {
    this.igChangeSub.unsubscribe();
  }


}
组件

import { Component } from '@angular/core';
import { TransactionServiceService } from './transaction-service.service';
import { Transaction } from './transaction';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  private readonly transactionService: TransactionServiceService;
  public transactions: Transaction[];
  constructor(transactionService: TransactionServiceService) {
    this.transactionService = transactionService;
    const transactions = [
      { name: 'Coles', amount: 27.8, category: 'Groceries' } as Transaction,
      { name: 'TransLink', amount: 20, category: 'Transportation' } as Transaction,
      { name: 'TransLink', amount: 25, category: 'Transportation' } as Transaction
    ];
    transactions.forEach(t => this.transactionService.addTransaction(t) );
  }
  getItems(): void {
    this.transactions = this.transactionService.getTransactions();
  }
  filterTransactions(category: string): void {
    this.transactions = this.transactionService.getTransactionsByCategory(category);
  }
}
模板

export class TransactionServiceService {
  private transactions: Transaction[];
  constructor() {
    this.transactions = [];
  }
  addTransaction(transaction: Transaction): Transaction[] {
    this.transactions.push(transaction);
    return this.transactions;
  }
  removeTransaction(transaction: Transaction): Transaction[] {
    return this.transactions.filter(t =>
      t.name !== transaction.name &&
      t.amount !== transaction.amount &&
      t.category !== transaction.category
    );
  }
  getTransactions(): Transaction[] {
    return this.transactions;
  }
  getTransactionsByCategory(category: string): Transaction[] {
    return this.transactions.filter( t => t.category === category);
  }
}
<button (click)="getItems()">Get All Items</button>
<button (click)="filterTransactions('Groceries')">Get Groceries</button>
<button (click)="filterTransactions('Transportation')">Get Transportation</button>
<div *ngFor="let transaction of transactions">{{transaction | json}}</div>
获取所有项目
买食品杂货
搭便车
{{transaction}json}

如果您试图获取最后一个事务,您可以轻松获取它,因为此方法使用
Array.push
。但是,我建议您在事务中添加一个标识符,以便更容易找到它们。

那么您基本上是在尝试创建一个服务来管理阵列并允许外部组件更新阵列?这是下一步。我现在只是想显示基于类别的数组。你有stackblitz吗?没有,我正在尝试创建一个,但它不起作用。我为你创建了一个。我的回答中提到了。所以你基本上是在尝试创建一个服务