简体   繁体   English

角度插值滞后呈现一些值以及如何从打字稿对象数组中删除一项

[英]Angular interpolation lags rendering some values & how to remove one item from the array of typescript objects

I am working on an ASP.NET Core - Angular web app where I can choose a customer as the origin and find distance & duration to others using Google maps distance matrix service . 我正在使用ASP.NET Core-Angular Web应用程序,在这里我可以选择客户作为来源,并使用Google Maps距离矩阵服务查找与他人的距离和持续时间 I am getting the values fine ( I think console log proves that the lag is not because of google maps API calls/accessing values from an array of objects ) but when I am binding data to the template using angular interpolation, it lags to render the distance & duration values. 我得到的值很好( 我认为控制台日志证明滞后不是由于google maps API调用/从对象数组访问值 ),但是当我使用角度插值将数据绑定到模板时,它滞后于渲染距离和持续时间值。 Also to mention, the table only displays once the button is clicked - when isFindButtonClicked becomes true . 另外要提一下,该表仅在单击按钮后才显示isFindButtonClicked变为true

  1. Can you help me find the cause and fix it? 您能帮我找到原因并解决吗?

在此处输入图片说明

customers: Array<Customer> = [];
nearbyCustomers: Array<Customer> = [];

getCustomers() {
        this.customerService.getAll()
            .subscribe( result => {
                this.customers = result;
            }, error => {
                this.alertService.error(error._body);
                this.router.navigate(['/home']);
            });
}

ngOnInit() {
        this.getCustomers();
}

Typescript function to find and assign distance/duration values: Typescript函数,用于查找和分配距离/持续时间值:

findNearbyCustomers(selectedId: number) {
    this.isFindButtonClicked = true;
    this.nearbyCustomers = this.customers;
    var origin = this.customers.find(c => c.id == selectedId);
    var originLatLng = origin.latitude.toString()+","+origin.longitude.toString();
    var service = new google.maps.DistanceMatrixService();

    for (let x = 0; x < this.customers.length; x++) {
            console.log(this.customers[x].id);
            var destinationLatLng = this.customers[x].latitude.toString()+","+this.customers[x].longitude.toString();

            service.getDistanceMatrix({
                origins: [originLatLng],
                destinations: [destinationLatLng],
                travelMode: google.maps.TravelMode.DRIVING
            }, (response, status) => {
                if (status.toString() == 'OK') {
                    console.log('Distance: '+response.rows[0].elements[0].distance.text+', Duration: '+response.rows[0].elements[0].duration.text);
                    this.nearbyCustomers[x].distance = response.rows[0].elements[0].distance.text;
                    this.nearbyCustomers[x].duration = response.rows[0].elements[0].duration.text;
                    console.log('DURATION: '+this.nearbyCustomers[x].duration+', DISTANCE:'+this.nearbyCustomers[x].distance);
                }
            })
    }
}

Partial markups from angular template: 角度模板的部分标记:

<tbody>
       <tr *ngFor="let nearbyCustomer of nearbyCustomers">
            <td>{{ nearbyCustomer.businessName }}</td>
            <td>
                <p>{{ nearbyCustomer.streetNumber + ' ' + nearbyCustomer.streetName + ', ' + nearbyCustomer.suburb }}</p>
                <p>{{ nearbyCustomer.city + ' ' + nearbyCustomer.postCode + ', ' + nearbyCustomer.country }}</p>
            </td>
            <td>{{ nearbyCustomer.contactPerson }}</td>
            <td>{{ nearbyCustomer.contactNumber }}</td>
            <td>{{ nearbyCustomer.email }}</td>
            <td>{{ nearbyCustomer.distance }}</td>
            <td>{{ nearbyCustomer.duration }}</td>
      </tr>
 </tbody>
  1. Also Previously, I've tried with an if statement if (this.customers[x].id != this.selectedDeliveryDestinationId) and only pushed customers excluding the selected one (as origin) this.nearbyCustomers.push(this.customers[x]); 同样在以前,我尝试使用if语句if (this.customers[x].id != this.selectedDeliveryDestinationId)并仅推送不包括所选客户(作为来源)的客户this.nearbyCustomers.push(this.customers[x]); and then when I tried to assign a value to object property & render it gave me Cannot set property 'distance' of undefined errors - seems I was messing with the index values. 然后,当我尝试为对象属性分配值并进行渲染时,它给我Cannot set property 'distance' of undefined错误的Cannot set property 'distance' of undefined -似乎我在弄乱索引值。 What should be the best way to exclude one item from the array for this purpose? 为此目的,从数组中排除一项的最佳方法是什么? Or, if I just can hide one specific row from HTML that would work as well. 或者,如果我只是可以从HTML隐藏一个特定的行,那么它也可以工作。

Thanks. 谢谢。

You need ngZone in this case to update your table. 在这种情况下,您需要ngZone来更新表。

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

in constructor add: private _ngZone: NgZone then in your getDistanceMatrix success: 在构造函数中添加: private _ngZone: NgZone然后在您的getDistanceMatrix中成功:

this._ngZone.run(() => {
                this.nearbyCustomers[x].distance = response.rows[0].elements[0].distance.text;
                    this.nearbyCustomers[x].duration = response.rows[0].elements[0].duration.text;
            });

About the second question I'll check it later and edit the answer 关于第二个问题,我待会再检查并编辑答案

Thanks for your answers. 感谢您的回答。 NgZone helped with the change detection lagging issue. NgZone帮助解决了变更检测滞后问题。 And for the second part of my question, here is how I fixed it (Not sure if this is the best solution but works fine for me) 对于我的问题的第二部分,这是我的解决方法(不确定这是否是最佳解决方案,但对我来说效果很好)

I've filtered the customers and only assigned values except the selected one like this: this.nearbyCustomers = this.customers.filter(c => c.id != this.selectedDeliveryDestinationId); 我已经过滤了客户,仅分配了价值,除了选定的价值,像这样: this.nearbyCustomers = this.customers.filter(c => c.id != this.selectedDeliveryDestinationId); . This way, I only had to loop through the array of nearbyCustomers excluding the origin -saving one API call waste in each loop :-) 这样,我只需要遍历不包括起点的附近客户数组-在每个循环中节省一个API调用浪费:-)

findNearbyCustomers() {
        this.isFindButtonClicked = true;
        this.nearbyCustomers = this.customers.filter(c => c.id != this.selectedDeliveryDestinationId);
        var origin = this.customers.find(c => c.id == this.selectedDeliveryDestinationId);
        var originLatLng = origin.latitude.toString()+","+origin.longitude.toString();
        var service = new google.maps.DistanceMatrixService();
        for (let x = 0; x < this.nearbyCustomers.length; x++) {
            var destinationLatLng = this.nearbyCustomers[x].latitude.toString()+","+this.nearbyCustomers[x].longitude.toString();        
            service.getDistanceMatrix({
                origins: [originLatLng],
                destinations: [destinationLatLng],
                travelMode: google.maps.TravelMode.DRIVING
            }, (response, status) => {
                if (status.toString() == 'OK') {
                    this._ngZone.run(() => {
                        this.nearbyCustomers[x].distance = response.rows[0].elements[0].distance.text;
                        this.nearbyCustomers[x].duration = response.rows[0].elements[0].duration.text;
                    })
                }
            })
        }
    }

I'd suggest to use a Pipe to filter the currently selected nearbyCustomer. 我建议使用管道过滤当前选定的附近的客户。

<tbody>
    <tr *ngFor="let nearbyCustomer of nearbyCustomers | nearbyCustomerFilter">
        <td>{{ nearbyCustomer.businessName }}</td>
        <td>
            <p>{{ nearbyCustomer.streetNumber + ' ' + nearbyCustomer.streetName + ', ' + nearbyCustomer.suburb }}</p>
            <p>{{ nearbyCustomer.city + ' ' + nearbyCustomer.postCode + ', ' + nearbyCustomer.country }}</p>
        </td>
        <td>{{ nearbyCustomer.contactPerson }}</td>
        <td>{{ nearbyCustomer.contactNumber }}</td>
        <td>{{ nearbyCustomer.email }}</td>
        <td>{{ nearbyCustomer.distance }}</td>
        <td>{{ nearbyCustomer.duration }}</td>
    </tr>
</tbody>

Create a Service which provides the information about the currently selected nearbyCustomer to the Pipe. 创建一个服务,该服务向管道提供有关当前选定的邻近客户的信息。

Then, whenever you choose another customer, your List gets updated an the Pipe kicks this particular entry out of the current view. 然后,每当您选择另一个客户时,您的列表都会被更新,并且管道会将特定条目踢出当前视图。

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

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