web-dev-qa-db-fra.com

Angular 4 - pousser un nouvel élément vers un tableau à partir d'un observable

J'ai une page où j'affiche une liste avec locations, et en cliquant sur chacun d'eux, j'affiche assets pour cela location. J'ai configuré le modèle comme ceci:

<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>

Et dans le composant, j'ai mis le tableau assets vide, et un currentLocation vide:

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

Et puis dans la méthode select je récupère les actifs comme ceci:

  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
      );
  }

Ce que je voudrais faire, c'est que puisque j'utilise le plugin glisser-déposer pour Angular je voudrais permettre à l'utilisateur de faire glisser des actifs d'un emplacement à un autre. Et puis Poussez temporairement cet actif dans un tableau assets. J'ai fait une fonction pour ça:

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

Ainsi, lorsqu'un utilisateur fait glisser et dépose l'actif d'un emplacement à un autre, je vide le tableau assets et je pousse le nouvel actif qui a été déplacé vers le tableau. Mais, dans la méthode select, j'obtiens tous les assets pour ce nouveau location dans lequel le asset a été déposé, et cela réécrit le assets. Comment puis-je pousser dans le même tableau ceux assets, de sorte que j'ai à la fois le nouveau asset ajouté et le assets de ce location que je reçois le point de terminaison du service? J'ai également essayé une autre approche, où je vidais d'abord les ressources du tableau, puis appelais et passais les nouvelles méthodes location et asset à select:

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

Et puis, dans la méthode select, j'ai défini le paramètre asset comme facultatif, puis je l'ai poussé dans le tableau assets après avoir obtenu tous les assets pour cela location du service:

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


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

Mais, cela n'a pas fonctionné, l'élément déposé à un nouvel emplacement n'a pas été affiché dans le modèle. Comment puis-je y parvenir?

5
Leff

Eh bien dans votre première approche, vous écrasez votre tableau assets dans votre fonction subscribe:

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

Donc, évidemment, le asset que vous avez temporairement enregistré dans ce tableau est perdu à ce stade.

Votre deuxième approche est plus logique, mais vous utilisez subscribe dans cet exemple:

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

Dans ce cas, la partie if (asset) ... est passée comme deuxième argument à votre appel subscribe qui est le error callback. Vous voulez le faire comme ceci:

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

J'espère que ça aide.

Mise à jour: je ne suis même pas sûr si cette partie if (asset) ..., la façon dont vous l'avez implémentée, fonctionne même comme rappel d'erreur. vous obtenez probablement une erreur si ce rappel est appelé car une fonction est attendue, pas une expression (mais comme je l'ai dit, je ne suis pas sûr de cela).

2
lexith