简体   繁体   English

如何在 Ionic Angular 应用程序中将函数引用为模板变量?

[英]How to refer a funtion as a template variable in Ionic Angular app?

I have an Order object and a Customer Object.我有一个Order object 和一个客户 Object。 The JSON payload for the Order object is like the following: Order object 的JSON payload如下所示:

{
  "order_number" : 1,
  "customer_id": 1
}

And this is the JSON payload for the Customer object这是Customer object 的JSON payload

{
  "customer_id": 1,
  "customer_name" : 1,
}

I have Orders page where I want to display the list of orders.我有订单页面,我想在其中显示订单列表。 But instead of order.customer_id it was to display the customer_name但不是order.customer_id而是显示customer_name

For the I have getCustomerById which takes the customer_id as a parameter and returns the customer_name .对于我有getCustomerById ,它将customer_id作为参数并返回customer_name

This is my OrdersPage class:这是我的OrdersPage class:

import { Component, OnInit } from '@angular/core';
import { OrderService } from '../../services/order.service';
import { Order } from '../../models/order.model';
import { NavController, LoadingController } from '@ionic/angular';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { CustomerService } from 'src/app/services/customer.service';
import { Customer } from 'src/app/models/customer.model';

@Component({
  selector: 'app-orders',
  templateUrl: './orders.page.html',
  styleUrls: ['./orders.page.scss'],
})
export class OrdersPage implements OnInit {
  sender;
  customerName: string;
  destinationName: string;
  // viewOrders = false;
  error;
  orders: Order[];
  subscription: Subscription;
  constructor(private orderService: OrderService,
              private navCtrl: NavController,
              private router: Router,
              private customerService: CustomerService
            ) { }

  ngOnInit() {
    this.orderService.refreshNeeded
      .subscribe(() => {
        this.getAllOrders();
      });
    this.getAllOrders();

  }

  getAllOrders() {

    this.orderService.getAllOrders().subscribe(
      (res: Order[]) => {
        this.orders = res;

      },
      (error) => {
        this.error = error;

      });
  }

  getCustomerById(customerId: number): string {

    this.customerService.getCustomerById(customerId).subscribe(
      (customer: Customer) => {
        this.customerName = customer.name;
      }
    );
    return this.customerName;
  }

}

This is orders.page.html这是orders.page.html

<ion-header>
  <ion-toolbar color="dark">
    <ion-button slot="end">
      <ion-menu-button> </ion-menu-button>
    </ion-button>
    <ion-title>Orders</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-row>
    <ion-col size-md="8" offset-md="2">
      <ion-row class="header-row ion-text-center">
        <ion-col>
          Order number
        </ion-col>
        <ion-col>
          Customer
        </ion-col>
      </ion-row>
      <ion-row *ngFor="let order of orders; let i = index" class="data-row ion-text-center">
        <ion-col>
          {{order.order_number}}
        </ion-col>
        <ion-col>
          {{order.customer_id}}
        </ion-col>

        <!-- <ion-col>
        {{getCustomerById(order?.customer_id)}}
      </ion-col> -->
      </ion-row>
    </ion-col>
  </ion-row>
</ion-content>

This html works but it returns the order.customer_id not the customer_name I have tried to get the name by calling the funtion in the template this way {{getCustomerById(order?.customer_id)}} doesn't work and no error in the console as well.这个 html 有效,但它返回order.customer_id而不是customer_name我试图通过以这种方式调用模板中的函数来获取名称{{getCustomerById(order?.customer_id)}}不起作用并且控制台中没有错误以及。

What is the best way to get the customer_name field in the order list?在订单列表中获取customer_name字段的最佳方法是什么?

This is my customer.service.ts这是我的customer.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import { Customer } from '../models/customer.model';
import { catchError, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class CustomerService {
  url = 'http://api.mydomain.com';

  constructor( ) { }

  getAllCustomers(): Observable<Customer[]> {
    return this.httpClient.get<Customer[]>(`${this.url}/customers`).pipe();
  }

  getCustomerById(id: number): Observable<Customer> {
    return this.httpClient.get<Customer>(`${this.url}/customer/${id}`).pipe();
  }


}

As mentionned by @Muhammad Umair it is not a good design to make a request to a server for each customer name.正如@Muhammad Umair 所提到的,为每个客户名称向服务器发出请求并不是一个好的设计。 Best is to make one request to fetch all wanted curstomer names.最好是发出一个请求来获取所有想要的客户名称。 The solution below do not take this into consideration.下面的解决方案没有考虑到这一点。

Best here is to use a pipe.这里最好使用 pipe。

"A pipe takes in data as input and transforms it to a desired output." “pipe 将数据作为输入并将其转换为所需的 output。” Angular doc Angular 文档

Notice that your request to get your curstomer name is asynchronous (this is why nothing is displayed in your template), here you need to use the async pipe as well:请注意,您获取 curstomer 名称的请求是异步的(这就是为什么模板中没有显示任何内容),在这里您还需要使用异步 pipe :

<ion-col> 
    {{ order.customer_id | getCustomerName | async }} 
</ion-col>

And here is the pipe (that you should insert into your declarations in your component's module.这是 pipe (您应该将其插入组件模块的声明中。

import { Pipe } from '@angular/core';

@Pipe({
  name: 'getCustomerName'
})
export class CustomerNamePipe {

  constructor(private customerService: CustomerService) { }

  transform(userIds, args) {
     return this.customerService.getCustomerById(curstomerId);
  }

}

Again not a great solution but given the circumstances as you cant change anything in the API.同样不是一个很好的解决方案,但鉴于您无法更改 API 中的任何内容的情况。 You can modify your file to this.您可以将文件修改为此。

import { Component, OnInit } from '@angular/core';
import { OrderService } from '../../services/order.service';
import { Order } from '../../models/order.model';
import { NavController, LoadingController } from '@ionic/angular';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { CustomerService } from 'src/app/services/customer.service';
import { Customer } from 'src/app/models/customer.model';

@Component({
  selector: 'app-orders',
  templateUrl: './orders.page.html',
  styleUrls: ['./orders.page.scss'],
})
export class OrdersPage implements OnInit {
  sender;
  customerName: string;
  destinationName: string;
  // viewOrders = false;
  error;
  orders: Order[];
  subscription: Subscription;
  constructor(private orderService: OrderService,
              private navCtrl: NavController,
              private router: Router,
              private customerService: CustomerService
            ) { }

  ngOnInit() {
    this.orderService.refreshNeeded
      .subscribe(() => {
        this.getAllOrders();
        this.getAllCustomers();
      });

    this.getAllOrders();
    this.getAllCustomers();

  }

  getAllOrders() {

    this.orderService.getAllOrders().subscribe(
      (res: Order[]) => {
        this.orders = res;

      },
      (error) => {
        this.error = error;

      });
  }

  getAllCustomers() {

    this.customerService.getAllCustomers().subscribe(
      (customers: Customer[]) => {
        this.customers = customers;
      }
      (error) => {
        this.error = error;

      });
  }

  getCustomerById(customerId: number): string {
    const customer = this.customers.filter(customer => customer.customer_id === customerId );
    return customer.customer_name;
  }

}

As @Noelmout mention using pipe I was able to get the customer_name with a little bit of change.正如@Noelmout 提到的那样,使用 pipe 我只需稍作改动即可获得customer_name

This is the CustomerNamePipe这是CustomerNamePipe

import { Pipe, PipeTransform } from '@angular/core';
import { CustomerService } from '../services/customer.service';
import { Customer } from '../models/customer.model';
import { pluck } from 'rxjs/operators';

@Pipe({
  name: 'getCustomerName'
})
export class CustomerNamePipe implements PipeTransform {

  customer: Customer;

  constructor(private customerService: CustomerService) { }

  transform(curstomerId, args) {
    return this.customerService.getCustomerById(curstomerId).pipe(pluck('customer_name'));

  }


}

This is the order.page.html这是订单.page.html

<ion-col> 
    {{ order.customer_id | getCustomerName | async }} 
</ion-col>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM