【问题标题】:Subscribing to a service as the length of the *ngFor array订阅服务作为 *ngFor 数组的长度
【发布时间】:2019-04-01 10:54:50
【问题描述】:

我有一个带有 ngFor 的 div 和一个在 div 内调用 sat popover 事件的按钮

<div *ngFor="let order of orders">
  <button mat-icon-button [satPopoverAnchorFor]="popover_address" (click)="openAddressView(order)">
   <mat-icon matTooltip="Edit Address" class="icon">edit_location</mat-icon>
  </button> 
</div>

<sat-popover (closed)="closeAddressView()" #popover_address horizontalAlign="end" hasBackdrop verticalAlign="center">
    <app-order-address></app-order-address>
</sat-popover>

在调用服务的组件中

openAddressView(order: any){
    this.popover_address.open();
    this.ordersService.getAdddresses(order);
}

并订阅服务如下。

import { Component, OnInit, OnDestroy, Input, ChangeDetectorRef, 
ViewChild } from '@angular/core';
import { AgmMap, AgmMarker, AgmCoreModule } from '@agm/core';
import { MapsAPILoader } from '@agm/core';
import { OrdersService } from '../../../Services/orders- 
service/orders.service';
import { SatPopover } from '@ncstate/sat-popover';

@Component({
  selector: 'app-order-address',
  templateUrl: './order-address.component.html',
  styleUrls: ['./order-address.component.scss']
})
export class OrderAddressComponent implements OnDestroy {
  title: string = 'address';
  lat: number = 33.8950888;
  lng: number = 35.5186542;
  zoom: number = 8;
  height: string = '500px';
  addresses: Array<any>;
  selectedAddressId: number;
  @ViewChild(AgmMap) private myMap: any;
  @ViewChild('mapContainer') mapContainer: any;
  @ViewChild(AgmMarker) AddressPin: any;

 constructor(private OrdersService: OrdersService, private cdr: 
ChangeDetectorRef) {

  this.OrdersService.loadClientAddresses.subscribe((response: any) => {
    this.addresses = response.addresses;
    this.selectedAddressId = response.selected_address.id;
    this.recenterMap(response.selected_address.lat, 
    response.selected_address.lon);
    console.log(response); // PRINTS 10 TIMES
    this.cdr.detectChanges();
  });

}

除了单击按钮打开弹出框外,一切正常。 console.log 打印为订单对象的长度。例如(如果我有 10 个订单,它将打印 10 次)

我希望它只在被点击时订阅服务。

【问题讨论】:

  • 它会分别调用console.log 10 次订阅中的代码吗? loadClientAddresses 方法只是一个 http 调用(使用 HttpClient)吗?
  • 你实际上订阅了服务方法10次,所以预期的行为是调用订阅内的代码10次(包括console.log)。更好的方案是在父组件上订阅一次服务,通过属性绑定将数据传递给子组件。

标签: javascript html angular angular-material


【解决方案1】:

可能是因为您有 10 个 app-order-address 实例。即使没有触发弹出窗口,组件也会为每个弹出窗口构造一个 app-order-address (?)...(在“constructor”方法的顶部使用“console.log”进行测试)

如果你有 10 个构造函数调用,你就有 10 次订阅。因此,当您单击一个按钮时,它会触发所有 10 个订阅。

您应该在父组件中移动一些逻辑(也许还要在 rxjs 中寻找“sharedReplay”)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-31
    • 2017-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2019-07-25
    相关资源
    最近更新 更多