2017-10-23 5 views
2

Ich kämpfe mit diesem seit Tagen und könnte Hilfe von etwas fortgeschritteneren Leuten brauchen :).rxjs/ngrx/groupby verschachtelte Werte

problem

Wie Sie auf meinem Bild sehen bekam ich die folgende Struktur.

habe ich n Aufgaben in einer beobachtbaren:

  • Aufgaben []
    • [0] Aufgabe id 1
      • [0] jobs []
        • [0 ] Job 1
          • ...
        • [2] job 3
          • Job-ID 3
          • ...
          • Referenz-ID 515

Was möchte ich tun?

Ich möchte alle meine Aufgaben durch die Referenz-ID gruppieren, so dass ich auf meine Observable aus dem HTML-über ionic zugreifen kann.

Test2 ist, was ich erreichen möchte, aber es gibt mir nicht das erwartete Ergebnis. Und auch wenn ich die Struktur oben und nicht nur die Jobs halten muss.

Wenn jemand helfen kann es eine große Hilfe sein würde :)

Grüße, Nosta

+0

Könnten Sie Ihr erwartetes Ergebnis klären? Sie gruppieren Aufgaben vor allem nach der Referenz-ID eines _ seiner Jobs, nach all seinen Jobs usw.? – concat

Antwort

0

Hier ist die Grundlage dessen, was ich glaube, Sie brauchen

const grouped$ = localTasksWithReference$.reduce((grouping, task) => { 

    // Get all referenceIds for the task 
    const referenceIds = task.jobs.reduce((references, job) => { 
    references.push(job.referenceId); 
    return references; 
    }, []); 

    // Add each referenceId and task to the grouping 
    referenceIds.forEach(referenceId => { 
    grouping[referenceId] = grouping[referenceId] || []; 
    // Ensure task only grouped once per referenceId 
    if (grouping[referenceId].indexOf(task) === -1) { 
     grouping[referenceId].push(task); 
    } 
    }) 

    return grouping; 
}, {}); 

Sie können sehen, es funktioniert und Nehmen Sie hier Anpassungen vor. CodePen

Die Ausgabe ist eine Observable eines Objekts, das für jedes einzelne Refe eine Eigenschaft besitzt renceId, und der Eigenschaftswert ist ein Array der Aufgaben mit Jobs, die diese referenceId haben.

{ 
    ref#1: [ 
     {taskId: 1, jobs: Array(3)} 
     {taskId: 2, jobs: Array(3)} 
    ], 
    ref#2: [ 
     {taskId: 1, jobs: Array(3)} 
     {taskId: 2, jobs: Array(3)} 
    ] 
} 

Sie müssen diese Ausgabe für eine angemessene Verwendung in der Vorlage gestalten. Wenn Sie Hilfe benötigen, zeigen Sie bitte die vorgeschlagene HTML-Struktur an.

Hinweis, ich habe angenommen, dass eine Aufgabe nur einmal pro referenceId angezeigt werden sollte.

0

Dank @Richard Matsen.

let localTasksWithReference = this._store.select(state => state.tasks) 
     .map((localTasks: Task[]) => { 
      return localTasks.filter((localTask: Task) => { 
       return this.typeCode.toString() === localTask.taskProcessTypeCode.toString(); 
      }) 
     }); 

    let referenceGroup = localTasksWithReference.reduce((grouping, tasks: any) => { 
     tasks.reduce((test, task) => { 
      let referenceIds = 
       task.jobs.reduce((references, job) => { 
        references.push(job.businessTransactionDocumentReference.id); 
        return references; 
       }, []); 

      referenceIds.forEach(referenceId => { 
       grouping[referenceId] = grouping[referenceId] || []; 
       if (grouping[referenceId].indexOf(task) === -1) { 
        grouping[referenceId].push(task); 
       } 
      }) 
     }, []); 
     console.log(grouping); 
     return grouping; 
    }, {}); 

this.tasksWithReference = referenceGroup; 
this.tasksWithReference.subscribe(console.log); 

Result

Arbeiten wie ein Charme. Aber ich könnte tatsächlich etwas Hilfe mit dem HTML brauchen.

Was ich tun möchte, ist die ReferenceId als Titel und die Aufgaben unten.

<ion-card> 
    <ion-list> 
    <ion-list-header *ngFor="let taskWithReference of tasksWithReference | async"> 
     test 
    </ion-list-header> 
    </ion-list> 
</ion-card> 

Ich denke, wir brauchen ein Array für das kein Objekt? Ich arbeite hier mit Ionen.

So sehen meine Arbeitsaufgaben aus und darüber sind meine gruppierten Referenzen.

references

0

Wenn jemand interessiert es zwei Möglichkeiten, dies zu lösen:

private getTasksWithReferenceOOOOOOOOLD() { 
    let localTasksWithReference = this._store.select(state => state.tasks) 
     .map((localTasks: Task[]) => { 
      return localTasks.filter((localTask: Task) => { 
       return this.typeCode.toString() === localTask.taskProcessTypeCode.toString(); 
      }) 
     }).reduce((grouping, tasks: any) => { 
      grouping = {}; 
      tasks.reduce((test, task) => { 
       let referenceIds = 
        task.jobs.reduce((references, job) => { 
         references.push(job.businessTransactionDocumentReference.id); 
         return references; 
        }, []); 


       referenceIds.forEach(referenceId => { 
        grouping[referenceId] = grouping[referenceId] || { "tasks": [] }; 
        if (grouping[referenceId].tasks.indexOf(task) === -1) { 
         grouping[referenceId].tasks.push(task); 
        } 
       }) 
      }, []); 
      const arr = Object.keys(grouping).reduce((arr, key) => 
       ([...arr, { ...grouping[key], key }]), // Can add key if you don't have it 
       []); 
      this.tasksWithReference = Observable.of(arr); 
      return arr; 
     }, {}).subscribe(); 
} 

Jetzt kann ich die referenceId mit dem Schlüssel zugreifen und die Aufgaben mit reference.tasks.

Zweite Lösung:

public tasksWithReferenceMap: Map<string, Task[]> 

public getTasksWithReference() { 
    this.tasksWithReference = this._store.select(state => state.tasks) 
     .map((localTasks: Task[]) => { 
      this.tasksWithReferenceMap = new Map<string, Task[]>(); 
      return localTasks.filter((localTask: Task) => { 
       return this.typeCode.toString() === localTask.taskProcessTypeCode.toString(); 
      }).reduce((grouping, task: Task) => { 
       // Get all referenceIds for the task 
       const referenceIds = task.jobs.reduce((references, job: Job) => { 
        references.push(job.businessTransactionDocumentReference.id); 
        return references; 
       }, []); 

       // Add each referenceId and task to the grouping 
       referenceIds.forEach(referenceId => { 
        grouping.set(referenceId, grouping.get(referenceId) || []); 
        if (grouping.get(referenceId).indexOf(task) === -1) { 
         grouping.get(referenceId).push(task); 
        } 
       }) 

       return grouping; 
      }, this.tasksWithReferenceMap); 
     }); 
} 

mit Karten arbeiten hier.

als müssen wir eine eigene Pfeife erstellen:

import { Task } from './../../models/task.model'; 
import { Pipe, PipeTransform } from '@angular/core'; 

@Pipe({ 
name: 'keys', 
}) 
@Pipe({ name: 'keys' }) 
export class KeysPipe implements PipeTransform 
{ 


transform(value: Map<string, Task[]>, args: string[]): any 
    { 
    let keys = []; 
    for (let key of value.keys()) 
    { 
     keys.push({ key: key }); 
    } 
    return keys; 
    } 
} 

und als Zugang der html:

<ion-list *ngFor="let reference of tasksWithReference | async | keys | orderBy: 'key' : reverseReference"> 
     <ion-list-header class="referenceListHeader"> 
      {{'REFERENCE' | translate}}: {{reference?.key}} 
     </ion-list-header> 
     <ion-item-sliding *ngFor="let task of tasksWithReferenceMap.get(reference?.key) | orderBy: 'id'; let i = index"> 

Dank für Sie wieder helfen, sonst wäre es etwas mehr Zeit genommen haben;)

Verwandte Themen