[英]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.