कोणीय सामग्री 2 डेटाटेबल नेस्टेड ऑब्जेक्ट्स के साथ छंटनी


83

मेरे पास एक सामान्य कोणीय सामग्री है 2 सॉर्ट करने योग्य हेडर के साथ डेटाटेबल। सभी प्रकार हेडर ठीक काम कर रहे हैं। मूल्य के रूप में एक वस्तु को छोड़कर। ये बिल्कुल नहीं छांटते हैं।

उदाहरण के लिए:

 <!-- Project Column - This should sort!-->
    <ng-container matColumnDef="project.name">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Project Name </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.project.name}} </mat-cell>
    </ng-container>

ध्यान दें element.project.name

यहाँ प्रदर्शन कॉलम कॉन्फ़िगर किया गया है:

 displayedColumns = ['project.name', 'position', 'name', 'test', 'symbol'];

काम 'project.name'करने के लिए 'project'नहीं बदल रहा है और न ही"project['name']"

मैं क्या खो रहा हूँ? क्या यह भी संभव है?

यहाँ एक Stackblitz है: कोणीय Material2 DataTable सॉर्ट ऑब्जेक्ट

संपादित करें: आपके सभी उत्तरों के लिए धन्यवाद। मैंने पहले ही इसे गतिशील डेटा के साथ काम कर लिया है। इसलिए मुझे हर नई नेस्टेड संपत्ति के लिए एक स्विच स्टेटमेंट नहीं जोड़ना है।

यहाँ मेरा समाधान है: (एक नया DataSource बनाना जो MatTableDataSource का विस्तार करता है आवश्यक नहीं है)

export class NestedObjectsDataSource extends MatTableDataSource<MyObjectType> {

  sortingDataAccessor: ((data: WorkingHours, sortHeaderId: string) => string | number) =
    (data: WorkingHours, sortHeaderId: string): string | number => {
      let value = null;
      if (sortHeaderId.indexOf('.') !== -1) {
        const ids = sortHeaderId.split('.');
        value = data[ids[0]][ids[1]];
      } else {
        value = data[sortHeaderId];
      }
      return _isNumberValue(value) ? Number(value) : value;
    }

  constructor() {
    super();
  }
}

1
क्या आप स्टैकब्लिट्ज़ को फिक्स के साथ अपडेट कर सकते हैं
सत्य राम

जवाबों:


168

इस पर दस्तावेज़ीकरण ढूंढना कठिन था, लेकिन यह संभव है कि उपयोग करके sortingDataAccessorऔर एक स्विच स्टेटमेंट द्वारा। उदाहरण के लिए:

@ViewChild(MatSort) sort: MatSort;

ngOnInit() {
  this.dataSource = new MatTableDataSource(yourData);
  this.dataSource.sortingDataAccessor = (item, property) => {
    switch(property) {
      case 'project.name': return item.project.name;
      default: return item[property];
    }
  };
  this.dataSource.sort = sort;
}

7
तुमने मुझे बचाया। धन्यवाद।
सीबास

1
आपको कहां sortसे मिलाthis.dataSource.sort = sort;
जॉय गफ़

3
मुझे ngAfterViewInitइसे काम करने के लिए जगह देना पड़ा
मेल

यह अच्छी तरह से काम किया, बस इसे ngAfterViewInit में रखा जैसा कि ऊपर टिप्पणी में बताया गया है।
वाॅल

यह मेरी मेज घोषणा के बगल में रखा और यह तुरंत काम किया। मुझे डिबगिंग का एक टन बचा लिया। धन्यवाद!
जेमी टीटी

30

आप ऑब्जेक्ट से गहराई से संपत्ति प्राप्त करने के लिए घटक में एक फ़ंक्शन लिख सकते हैं। फिर dataSource.sortingDataAccessorनीचे की तरह इसका उपयोग करें

getProperty = (obj, path) => (
  path.split('.').reduce((o, p) => o && o[p], obj)
)

ngOnInit() {
  this.dataSource = new MatTableDataSource(yourData);
  this.dataSource.sortingDataAccessor = (obj, property) => this.getProperty(obj, property);
  this.dataSource.sort = sort;
}

columnDefs = [
  {name: 'project.name', title: 'Project Name'},
  {name: 'position', title: 'Position'},
  {name: 'name', title: 'Name'},
  {name: 'test', title: 'Test'},
  {name: 'symbol', title: 'Symbol'}
];

और html में

<ng-container *ngFor="let col of columnDefs" [matColumnDef]="col.name">
      <mat-header-cell *matHeaderCellDef>{{ col.title }}</mat-header-cell>
      <mat-cell *matCellDef="let row">
        {{ getProperty(row, col.name) }}
      </mat-cell>
  </ng-container>

1
यह सबसे अच्छा समाधान, छोटा और संक्षिप्त प्रतीत होता है, और यह स्विच के रूप में सीमित नहीं है।
Ivar Kallejärv

मैं वास्तव में इस कार्यान्वयन को पसंद करता हूं। उस कोड पर कटौती करता है जिसे उपयोग / उत्पन्न करना है। मैं पहले से इस के साथ चटाई तालिकाओं के अंतिम कार्यान्वयन के साथ एक समस्या में भाग गया, ताज़ा मुद्दे पैदा कर रहे थे। यह हालांकि साफ है।
एलपी

3
मुझे यह उपाय भी पसंद हैं। मैं lodashअपनी परियोजना में उपयोग करता हूं इसलिए यदि आप उपयोग करते हैं lodash, तो यह समाधान इसका अनुवाद करता है: this.dataSource.sortingDataAccessor = _.get;गहरी संपत्ति की पहुंच को सुदृढ़ करने की कोई आवश्यकता नहीं है।
एंडी

1
@ कैंडी आपको इसका एक अलग जवाब देना चाहिए। यह एक टिप्पणी में सच होने के लिए बहुत आसान लगता है .. कि मुझे क्या करना है?
सिमोन_विवर

11

दिए गए उत्तर को छोटा भी किया जा सकता है, किसी भी स्विच की आवश्यकता नहीं है, जब तक आप खेतों के लिए डॉट नोटेशन का उपयोग नहीं करते हैं।

ngOnInit() {
  this.dataSource = new MatTableDataSource(yourData);

  this.dataSource.sortingDataAccessor = (item, property) => {
     if (property.includes('.')) return property.split('.').reduce((o,i)=>o[i], item)
     return item[property];
  };

  this.dataSource.sort = sort;
}

5

मुझे @Hieu_Nguyen समाधान पसंद हैं। मैं सिर्फ इतना जोड़ता हूं कि यदि आप प्रोजेक्ट में लैश का उपयोग करते हैं जैसा कि मैं करता हूं तो समाधान इसका अनुवाद करता है:

import * as _ from 'lodash';

this.dataSource.sortingDataAccessor = _.get; 

गहरी संपत्ति की पहुंच को सुदृढ़ करने की आवश्यकता नहीं है।


1
अद्भुत काम करता है, लेकिन संघर्षरत किसी के लिए: आपको displayedColumnsमूल्यों के मार्ग के रूप में नाम देना चाहिए , ['title', 'value', 'user.name'];और फिर <ng-container matColumnDef="user.name">अपने टेम्पलेट में उपयोग करना चाहिए ।
जेफरी रोसडेन्गल

वैकल्पिक रूप से, आप कॉलम के नाम को छोड़ सकते हैं और SortHeaderId को स्वतंत्र रूप से ओवरराइड कर सकते हैं mat-sort-headerजैसेmat-sort-header="user.name"
p4m

4

मैं एक सामान्य विधि का उपयोग करता हूं जो आपको एक dot.seperated.path के साथ mat-sort-headerया का उपयोग करने की अनुमति देता है matColumnDef। यदि यह पथ द्वारा तय की गई संपत्ति नहीं पा सकता है तो यह चुपचाप अपरिभाषित लौट आता है।

function pathDataAccessor(item: any, path: string): any {
  return path.split('.')
    .reduce((accumulator: any, key: string) => {
      return accumulator ? accumulator[key] : undefined;
    }, item);
}

आपको बस डेटा एक्सेसर सेट करना होगा

this.dataSource.sortingDataAccessor = pathDataAccessor;

1

मैंने कई नेस्टेड ऑब्जेक्ट स्तर के लिए अनुकूलित किया है।

this.dataSource.sortingDataAccessor =
  (data: any, sortHeaderId: string): string | number => {
    let value = null;
    if (sortHeaderId.includes('.')) {
      const ids = sortHeaderId.split('.');
      value = data;
      ids.forEach(function (x) {
        value = value? value[x]: null;
      });
    } else {
      value = data[sortHeaderId];
    }
    return _isNumberValue(value) ? Number(value) : value;
  };

आपके समाधान से मुझे सबसे ज्यादा मदद मिली क्योंकि मुझे एहसास हुआ कि मैं नंबर या स्ट्रिंग वापस कर सकता हूं। मेरी तालिका में दोनों प्रकार हैं और उन्हें क्रमबद्ध करने की आवश्यकता है जहां संख्याओं को संख्यात्मक रूप से क्रमबद्ध किया गया था और तार की तरह नहीं। टर्नरी ऑपरेटर का उपयोग करना जो टाइपिंग की जांच करता है, समाधान की कुंजी थी।
१०:२३ बजे ११

मुझे मिल गया Cannot find name '_isNumbervalue, और यह मानते हुए कि यह एक लॉश विधि है, मैं नोड मॉड्यूल में विधि नहीं ढूँढ सकता। isNumberमौजूद। मैं पहले से दर्ज होने से परिचित नहीं हूँ अगर यह क्या है। मैं इसका प्रयोग कैसे करूं?
रिन और लेन

1
आयात @ _isNumberValue} से "@ कोणीय / सीडीके / जबरदस्ती";
ई.सरौत

1

एक अन्य विकल्प, कि कोई भी यहां से बाहर नहीं निकला, पहले स्तंभ को समतल करें ...

yourData.map((d) => 
   d.flattenedName = d.project && d.project.name ? 
                     d.project.name : 
                     'Not Specified');

this.dataSource = new MatTableDataSource(yourData);

बस एक और विकल्प, प्रत्येक के लिए पेशेवरों और विपक्ष!


1

बस इसे अपने डेटा स्रोत में जोड़ें और आप नेस्टेड ऑब्जेक्ट तक पहुंचने में सक्षम होंगे

this.dataSource.sortingDataAccessor = (item, property) => {
    // Split '.' to allow accessing property of nested object
    if (property.includes('.')) {
        const accessor = property.split('.');
        let value: any = item;
        accessor.forEach((a) => {
            value = value[a];
        });
        return value;
    }
    // Access as normal
    return item[property];
};

0

यह तत्व ['project.name'] के आधार पर छाँटने की कोशिश कर रहा है। जाहिर है कि तत्व के पास ऐसी कोई संपत्ति नहीं है।

कस्टम डेटा स्रोत बनाना आसान होना चाहिए जो MatTableDatasource का विस्तार करता है और नेस्टेड ऑब्जेक्ट गुणों द्वारा सॉर्टिंग का समर्थन करता है। कस्टम स्रोत का उपयोग करने पर material.angular.io डॉक्स में उदाहरण देखें।


0

मेरे पास एक ही मुद्दा था, पहले प्रस्ताव का परीक्षण करके मुझे कुछ त्रुटियां थीं, मैं इसे "स्विच (संपत्ति)" जोड़कर ठीक कर सकता था

this.dataSource.sortingDataAccessor =(item, property) => {
    switch (property) {
    case 'project.name': return item.project.name;

    default: return item[property];
    }
  };

0

MatTableDataSource का उपयोग करें करें पूर्ण MatSort समस्या समाधान की जाँच

HTML में

    <ng-container matColumnDef="createdDate" @bounceInLeft>
      <th mat-header-cell *matHeaderCellDef mat-sort-header class="date"> Created date
      </th>
          <td mat-cell *matCellDef="let element" class="date"> {{element.createdDate
           | date :'mediumDate'}} </td>
   </ng-container>

  <ng-container matColumnDef="group.name">
    <th mat-header-cell *matHeaderCellDef mat-sort-header class="type"> Group </th>
    <td mat-cell *matCellDef="let element" class="type"> {{element.group.name}} </td>
  </ng-container>

@ViewChild(MatSort, { static: true }) sort: MatSort;

    ngOnInit() {
      this.dataSource = new MatTableDataSource(yourData);
      this.dataSource.sortingDataAccessor = (item, property) => {
    switch(property) {
      case 'project.name': return item.project.name;
      default: return item[property];
    }
  };
  this.dataSource.sort = sort;
}

0

यदि आप कुछ विस्तारित सुविधाओं के साथ एक कोणीय सामग्री तालिका चाहते हैं, जैसे नेस्टेड वस्तुओं के लिए छंटनी https://github.com/mikelgo/ngx-mat-table-extensions/blob/master/libs/lx-mat पर एक नज़र है -table / README.md

मैंने यह परिवाद बनाया है क्योंकि मुझे बॉक्स से बाहर चटाई-टेबल की कुछ विशेषताएं याद आ रही थीं।

उन्नत छँटाई @Hieu गुयेन द्वारा सुझाए गए उत्तर के समान है, लेकिन थोड़ा बढ़ाया भी ऊपरी और छोटे मामले पत्र द्वारा उचित छँटाई है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.