如何在 Ionic Angular 应用程序中将函数引用为模板变量?
How to refer a funtion as a template variable in Ionic Angular app?
我有一个 Order
对象和一个客户对象。 Order
对象的 JSON payload
如下所示:
{
"order_number" : 1,
"customer_id": 1
}
这是 Customer
对象的 JSON payload
{
"customer_id": 1,
"customer_name" : 1,
}
我有一个订单页面,我想在其中显示订单列表。但不是 order.customer_id
而是显示 customer_name
因为我有 getCustomerById
将 customer_id
作为参数,returns 将 customer_name
作为参数。
这是我的 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;
}
}
这是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>
这个 html 有效,但 returns order.customer_id
而不是 customer_name
我试图通过这种方式调用模板中的函数来获取名称 {{getCustomerById(order?.customer_id)}}
不起作用并且控制台中也没有错误。
获取订单列表中 customer_name
字段的最佳方法是什么?
这是我的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();
}
}
正如@Muhammad Umair 所提到的,为每个客户名称向服务器发出请求并不是一个好的设计。最好是发出一个请求来获取所有想要的用户姓名。下面的解决方案没有考虑到这一点。
这里最好是使用管道。
"A pipe takes in data as input and transforms it to a desired output."
Angular 文档
请注意,您获取光标名称的请求是异步的(这就是模板中不显示任何内容的原因),此处您还需要使用异步管道:
<ion-col>
{{ order.customer_id | getCustomerName | async }}
</ion-col>
这是管道(您应该将其插入组件模块的声明中。
import { Pipe } from '@angular/core';
@Pipe({
name: 'getCustomerName'
})
export class CustomerNamePipe {
constructor(private customerService: CustomerService) { }
transform(userIds, args) {
return this.customerService.getCustomerById(curstomerId);
}
}
同样不是一个很好的解决方案,但考虑到您无法更改 API 中的任何内容的情况。你可以把你的文件修改成这样。
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;
}
}
正如@Noelmout 提到的使用管道,我能够通过一点点改变得到 customer_name
。
这是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'));
}
}
这是order.page.html
<ion-col>
{{ order.customer_id | getCustomerName | async }}
</ion-col>
我有一个 Order
对象和一个客户对象。 Order
对象的 JSON payload
如下所示:
{
"order_number" : 1,
"customer_id": 1
}
这是 Customer
对象的 JSON payload
{
"customer_id": 1,
"customer_name" : 1,
}
我有一个订单页面,我想在其中显示订单列表。但不是 order.customer_id
而是显示 customer_name
因为我有 getCustomerById
将 customer_id
作为参数,returns 将 customer_name
作为参数。
这是我的 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;
}
}
这是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>
这个 html 有效,但 returns order.customer_id
而不是 customer_name
我试图通过这种方式调用模板中的函数来获取名称 {{getCustomerById(order?.customer_id)}}
不起作用并且控制台中也没有错误。
获取订单列表中 customer_name
字段的最佳方法是什么?
这是我的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();
}
}
正如@Muhammad Umair 所提到的,为每个客户名称向服务器发出请求并不是一个好的设计。最好是发出一个请求来获取所有想要的用户姓名。下面的解决方案没有考虑到这一点。
这里最好是使用管道。
"A pipe takes in data as input and transforms it to a desired output." Angular 文档
请注意,您获取光标名称的请求是异步的(这就是模板中不显示任何内容的原因),此处您还需要使用异步管道:
<ion-col>
{{ order.customer_id | getCustomerName | async }}
</ion-col>
这是管道(您应该将其插入组件模块的声明中。
import { Pipe } from '@angular/core';
@Pipe({
name: 'getCustomerName'
})
export class CustomerNamePipe {
constructor(private customerService: CustomerService) { }
transform(userIds, args) {
return this.customerService.getCustomerById(curstomerId);
}
}
同样不是一个很好的解决方案,但考虑到您无法更改 API 中的任何内容的情况。你可以把你的文件修改成这样。
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;
}
}
正如@Noelmout 提到的使用管道,我能够通过一点点改变得到 customer_name
。
这是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'));
}
}
这是order.page.html
<ion-col>
{{ order.customer_id | getCustomerName | async }}
</ion-col>