typescript Angular 4 - 将新项目从可观察对象推送到数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44451988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:37:13  来源:igfitidea点击:

Angular 4 - pushing a new item to an array from an observable

javascriptarraysangulartypescriptobservable

提问by Leff

I have a page where I display a list with locations, and clicking on each of them I am displaying assetsfor that location. I have set up the template like this:

我有一个页面,我在其中显示一个列表locations,然后单击我assets为此显示的每个列表location。我已经设置了这样的模板:

<li
    *ngFor="let location of locations"
    (click)="select(location)"
    droppable
    [dragOverClass]="'drag-target-border'"
    (onDrop)="onItemDrop($event, location)"
    >
      {{ location.name }}
      <ul *ngIf="currentLocation == location && assetsVisible">
        <ng-container *ngIf="currentLocation.assets?.length > 0;else message">
          <li
            *ngFor="let asset of currentLocation.assets"
            class="asset"
            draggable
            [dragData]="asset"
            >
            <p>{{ asset.title }}</p>
            <p>{{ asset.address }}</p>
            <p>{{ asset.value }}</p>
          </li>
        </ng-container>
        <ng-template #message>No assets for {{ location.name }}</ng-template>
      </ul>
  </li>

And in the component, I have set the empty assetsarray, and an empty currentLocation:

在组件中,我设置了空assets数组和一个空数组currentLocation

  locations: any[] = [];
  currentLocation: any = {};
  assets: any[] = [];

And then in the method selectI am fetching the assets like this:

然后在方法中select我获取这样的资产:

  select(location:any = {){

    if (this.currentLocation != location || !this.assetsVisible) {
      this.assetsVisible = true;
    }
    else {
      this.assetsVisible = false;
    }

    this.currentAddress = address;

    this.locationService.getAssets(location.Id)
      .subscribe(
        assets => this.assets = assets
      );
  }

What I would like to do is to since I am using the drag and drop plugin for AngularI would like to make it possible for user to drag assets from one location to another. And then just temporarily push that asset to an array assets. I have made a function for that:

我想做的是因为我使用的是 Angular 的拖放插件,所以我想让用户可以将资产从一个位置拖到另一个位置。然后只是暂时将该资产推送到数组assets。我为此做了一个功能:

onItemDrop(e: any, location:any = {}) {
   this.assets = [];
   this.assets.push(e.dragData);        
   this.select(location);
}

So, when a user drags and drops the asset from one location to another, I am emptying the assetsarray, and pushing the new asset that was dragged to the array. But, then in the selectmethod I am getting all the assetsfor that new locationthat the assetwas dropped to, and that rewrites the assetsarray. How can I push to the same array those assets, so that I have both the new assetadded and the assetsof that locationthat I get from the service endpoint? I have tried another approach as well, where I was first emptying array assets, and then calling and passing new locationand new assetto selectmethod:

因此,当用户将资产从一个位置拖放到另一个位置时,我正在清空assets数组,并将被拖动到数组的新资产推送。但是,然后在该select方法中,我获得了被删除的assets那个新的所有内容,并重写了数组。我怎么能推到同一个阵列的,所以我有两个新加入和那,我从服务端点得到什么?我也尝试过另一种方法,我首先清空数组资产,然后调用并将 new和 new传递给方法:locationassetassetsassetsassetassetslocationlocationassetselect

onItemDrop(e: any, location:any = {}) {
    this.assets = [];
    this.select(location, e.dragData);
  }

And then, in the selectmethod I have set the assetparameter as optional, and then pushing it there to the assetsarray after I got all the assetsfor that locationfrom the service:

然后,在select方法中,我将asset参数设置为可选,然后assets在我从服务中assets获取所有参数后将其推送到数组中location

select(location:any = {}, asset?:any = {}) {


    this.locationService.getAssets(location.Id)
      .subscribe(
        assets => this.assets = assets,
        if (asset) {this.assets.push(asset)} 
      );
  }

But, that didn't work, the asset dropped to new location wasn't displayed in the template. How can I achieve that?

但是,这不起作用,模板中没有显示放置到新位置的资产。我怎样才能做到这一点?

采纳答案by lexith

Well in your first approach, you're overwriting your assetsarray in your subscribefunction:

那么在您的第一种方法中,您将assets在您的subscribe函数中覆盖您的数组:

this.locationService.getAssets(location.Id).subscribe(
    assets => this.assets = assets
);

So obviously, the assetyou temporarily saved in that array is lost at this point.

很明显,asset您暂时保存在该数组中的内容此时丢失了。

Your second approach makes more sense, but you're using subscribewrong in this example:

您的第二种方法更有意义,但您subscribe在此示例中使用错误:

this.locationService.getAssets(location.Id).subscribe(
    assets => this.assets = assets,
    if (asset) {this.assets.push(asset)} 
);

In this case the if (asset) ...part is passed as the second argument to your subscribecall which is the error callback. You want to do it like this:

在这种情况下,该if (asset) ...部分作为第二个参数传递给您的subscribe调用,即error callback. 你想这样做:

this.locationService.getAssets(location.Id).subscribe( (assets) => {
    this.assets = assets;
    if (asset) {
         this.assets.push(asset)
    } 
});

Hope it helps.

希望能帮助到你。

Update: I'm not even sure if that if (asset) ...part, the way you implemented it, is even working as error callback. you probably get an error there if that callback is called because a function is expected, not an expression (but as i said, i'm not sure about that).

更新:我什至不确定那if (asset) ...部分,你实现它的方式,是否甚至可以作为错误回调。如果因为需要函数而不是表达式而调用该回调,则您可能会在那里收到错误消息(但正如我所说,我不确定)。