【问题标题】:Detecting Changes Coming Into View in Angular App and Preventing Repeated Firing of POST Request检测 Angular 应用程序中进入视图的更改并防止重复触发 POST 请求
【发布时间】:2018-04-17 17:04:50
【问题描述】:

在我的 Angular 应用程序中,我通过 Angular 的事件发射器将一些用户选择的过滤器值从一个组件传递到另一个组件。所以接收组件视图看起来像这样:

<data-view [records]="records"
    (sendCache)="onValuesReceived($event, type = 'location')"
    (sendOrigFile)="onValuesReceived($event, type = 'origFile')"
    (sendStart)="onValuesReceived($event, type = 'start')"
    (sendEnd)="onValuesReceived($event, type = 'end')">
</data-view>

然后我会像这样处理这些过滤器选择:

public typesProcess(value, type) {
  if (value && type) { this.filters[type] = value; }
    return this.filters;
}

然后将这些选择保存在 onValuesReceived() 函数中的“选择”变量中。因此,只要将事件发射到组件中就会触发此函数(这就是问题所在,因为有多个事件发射器,它会导致此处的 POST 请求多次触发 - 即使值没有更改):

public onValuesReceived(value, type) {
    let selections = this.filtersService.typesProcess(value, type);

    let fn = resRecordsData => {
        this.records = resRecordsData;
        let data = resRecordsData.data;
    };

     this.filtersService.getByFilters(
        // send values;
}

基于下面的 cmets,听起来最好的选择可能是将它们全部收集并通过一个事件发射器发送它们。这将解决每次这些事件发射器之一到达时多次触发 API POST 请求的问题。

【问题讨论】:

  • 没有。没有生命周期挂钩。以下是可用的:angular.io/guide/lifecycle-hooks
  • 过去几天你用相同的代码问了很多关于这个的问题。也许你应该以完全不同的方式看待这个问题。您的data-view 组件是否有理由需要所有这些输出,或者您可以只拥有一个并立即推送所有更改吗?
  • 很难从代码 sn-ps 中清楚地了解您的组件布局,但是您是否尝试过在 processByTypes() 方法中调用 onFilterReceived() 而不是返回过滤器。
  • @Muirik 您可以从事件 (EventEmitter) 中发出您想要的任何对象。这完全取决于您。
  • 我会研究那个选项。如果可行,它将解决许多问题。诀窍是在使用一个事件发射器传递时跟踪类型和值。

标签: javascript angular typescript


【解决方案1】:

虽然我们关于如何以及何时发送参数进行过滤的方法,我将发布我的方法:

search.component.ts:我的过滤器输入在哪里。

private triggerSelectionChange() {
    if (!this.isAtListings) {
        return;
    }
    const params = new SearchParameters();

    params.distance = this.selectedDistance;
    params.categoryName = this.categoryName;
    let geoLatLng;
    if (this.selectedLocation && Array.isArray(this.selectedLocation._geoloc)) {
        geoLatLng = this.selectedLocation._geoloc[0];
    } else {
        geoLatLng = this.selectedLocation ? this.selectedLocation._geoloc : this.latlngObj;
    }

    if (geoLatLng) {
        params.lat = geoLatLng.lat;
        params.lng = geoLatLng.lng;
    }

    params.placesId = this.selectedLocation ? this.selectedLocation.objectID : '';
    params.kidFriendly = this.kidFriendly.toString();
    params.petFriendly = this.petFriendly.toString();
    params.handicappedAccessible = this.handicappedAccessible.toString();

    this.optionsChanged.emit(params);
}

    onDistanceChange(e) {
         const distance = parseInt(e, 10);
         this.selectedDistance = isNaN(distance) ? e : distance;
         this.radius = isNaN(distance) ? 'all' : (distance * 1609);
         this.triggerSelectionChange();
    }

    onCategoryChange(e) {
         this.selectedCategory = e;
         this.categoryName = '';
         for (const cat of this.categories) {
            if (cat.name === e) {
                this.categoryName = e;
                break;
            }
        }
        this.triggerSelectionChange();
    }

    // more filters down

listings.component.tssearch.component 的父级以及显示结果的位置。

searchParametersChanged(params: SearchParameters) {
    this.searchParams$.next(params);
    // instead of calling another Observable like I do here, you can use the params to actually do your POST request.
}

要点是在triggerSelectionChange() 中处理您的过滤器,然后将所需的值发送给父级。

【讨论】:

  • 在上面添加了更多代码,如果有帮助的话。我会尽快看看你的解决方案。
猜你喜欢
  • 2020-03-30
  • 2022-08-08
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 2020-08-19
相关资源
最近更新 更多