कोणीय + सामग्री - डेटा स्रोत (मैट-टेबल) को कैसे ताज़ा करें


120

मैं चुने हुए भाषाओं के उपयोगकर्ताओं की सामग्री को सूचीबद्ध करने के लिए एक चटाई-तालिका का उपयोग कर रहा हूं । वे संवाद पैनल का उपयोग करके नई भाषाएँ भी जोड़ सकते हैं। बाद में उन्होंने एक भाषा जोड़ी और वापस लौट आए। मैं चाहता हूं कि मेरे डेटासोर्स ने उन परिवर्तनों को दिखाने के लिए ताज़ा किया।

मैं डेटास्टोर को एक सेवा से उपयोगकर्ता डेटा प्राप्त करके और ताज़ा विधि में एक डेटा स्रोत में पास करके आरंभ करता हूं।

Language.component.ts

import { Component, OnInit } from '@angular/core';
import { LanguageModel, LANGUAGE_DATA } from '../../../../models/language.model';
import { LanguageAddComponent } from './language-add/language-add.component';
import { AuthService } from '../../../../services/auth.service';
import { LanguageDataSource } from './language-data-source';
import { LevelbarComponent } from '../../../../directives/levelbar/levelbar.component';
import { DataSource } from '@angular/cdk/collections';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { MatSnackBar, MatDialog } from '@angular/material';

@Component({
  selector: 'app-language',
  templateUrl: './language.component.html',
  styleUrls: ['./language.component.scss']
})
export class LanguageComponent implements OnInit {

  displayedColumns = ['name', 'native', 'code', 'level'];
  teachDS: any;
  user: any;

  constructor(private authService: AuthService, private dialog: MatDialog) { }

  ngOnInit() {
    this.refresh();
  }

  add() {
    this.dialog.open(LanguageAddComponent, {
      data: { user: this.user },
    }).afterClosed().subscribe(result => {
      this.refresh();
    });
  }

  refresh() {
    this.authService.getAuthenticatedUser().subscribe((res) => {
      this.user = res;
      this.teachDS = new LanguageDataSource(this.user.profile.languages.teach);   
    });
  }
}

भाषा-डेटा-source.ts

import {MatPaginator, MatSort} from '@angular/material';
import {DataSource} from '@angular/cdk/collections';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';

export class LanguageDataSource extends DataSource<any> {

  constructor(private languages) {
    super();
  }

  connect(): Observable<any> {
    return Observable.of(this.languages);
  }

  disconnect() {
    // No-op
  }

}

इसलिए मैंने एक रीफ्रेश विधि को कॉल करने का प्रयास किया है, जहां मुझे उपयोगकर्ता को बैकएंड से फिर से मिलता है और फिर मैं डेटा स्रोत को फिर से संगठित करता हूं। हालांकि यह काम नहीं करता है, कोई भी बदलाव नहीं हो रहा है।


1
आप "डेटा स्रोत से" परिवर्तन ट्रिगर करना चाहते हैं, तो कृपया एक पर नजर है stackoverflow.com/questions/47897694/...
Yennefer

इस मामले में इवेंट इमेटर्स का उपयोग किया जा सकता है। stackoverflow.com/a/44858648/8300620
रोहित पार्ट

जवाबों:


58

नए डेटा प्राप्त करने के बाद विधि ChangeDetectorRefमें उपयोग करके एक परिवर्तन का पता लगाने के लिए refresh(), कंस्ट्रक्टर में ChangeDetectorRef इंजेक्षन करें और इस तरह डिटेक्शन का उपयोग करें:

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { LanguageModel, LANGUAGE_DATA } from '../../../../models/language.model';
import { LanguageAddComponent } from './language-add/language-add.component';
import { AuthService } from '../../../../services/auth.service';
import { LanguageDataSource } from './language-data-source';
import { LevelbarComponent } from '../../../../directives/levelbar/levelbar.component';
import { DataSource } from '@angular/cdk/collections';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { MatSnackBar, MatDialog } from '@angular/material';

@Component({
  selector: 'app-language',
  templateUrl: './language.component.html',
  styleUrls: ['./language.component.scss']
})
export class LanguageComponent implements OnInit {
  displayedColumns = ['name', 'native', 'code', 'level'];
  teachDS: any;

  user: any;

  constructor(private authService: AuthService, private dialog: MatDialog,
              private changeDetectorRefs: ChangeDetectorRef) { }

  ngOnInit() {
    this.refresh();
  }

  add() {
    this.dialog.open(LanguageAddComponent, {
      data: { user: this.user },
    }).afterClosed().subscribe(result => {
      this.refresh();
    });
  }

  refresh() {
    this.authService.getAuthenticatedUser().subscribe((res) => {
      this.user = res;
      this.teachDS = new LanguageDataSource(this.user.profile.languages.teach);
      this.changeDetectorRefs.detectChanges();
    });
  }
}

9
यह काम करने लगता है, क्या यह करने का उचित तरीका है? थोड़ा हैकी लगता है ...
Kay

अन्य तरीके क्या हैं? क्या आप पूर्ण उत्तर के लिए अपने समाधान में उदाहरण प्रदान कर सकते हैं?
Kay


88

मुझे नहीं पता ChangeDetectorRefकि प्रश्न बनाने के दौरान क्या आवश्यक था, लेकिन अब यह पर्याप्त है:

import { MatTableDataSource } from '@angular/material/table';

// ...

dataSource = new MatTableDataSource<MyDataType>();

refresh() {
  this.myService.doSomething().subscribe((data: MyDataType[]) => {
    this.dataSource.data = data;
  }
}

उदाहरण:
स्टैकब्लिट्ज़


4
हालांकि यह समाधान वास्तव में काम करता है, यह सामग्री पेजिनेटर को गड़बड़ कर देता है यदि तत्व परिणामों के पहले पृष्ठ के अलावा कहीं और जोड़ा जाता है। मैं समझता हूं कि यह इस प्रश्न के दायरे से बाहर है लेकिन चूंकि दोनों संबंधित हैं, क्या आपके पास उस समस्या का त्वरित समाधान है जो आप अपने उत्तर में जोड़ सकते हैं?
नाइट

5
@ रात को मुझे लगता है MatTableDataSource.paginatorकि पेजिनेटर के दृष्टिकोण को शुरू करने के बाद आपको संपत्ति को पेजिनेटर को सौंपना होगा। paginatorसंपत्ति का विवरण यहां देखें : material.angular.io/computers/table/api#MatTableDataSource
मार्टिन श्नाइडर

अच्छा संदर्भ। मैंने पहले वाले डॉक्स में नहीं देखा था। धन्यवाद!
नाइट

2
@ MA-Maddin आप इसे कैसे करना है पर अधिक विशिष्ट हो सकते हैं? उदाहरण?
नाथनफैन

@Nathanphan देर से, लेकिन एक उदाहरण जोड़ा;)
मार्टिन श्नाइडर

46

इसलिए मेरे लिए, किसी ने भी उस समस्या का अच्छा जवाब नहीं दिया जो मुझे मिला था जो @Kay से लगभग समान है। मेरे लिए यह छँटाई के बारे में है, छँटाई तालिका चटाई में परिवर्तन नहीं होता है। मैं इसका उत्तर देता हूं क्योंकि यह एकमात्र ऐसा विषय है जो मुझे Google पर खोज कर आता है। मैं कोणीय 6 का उपयोग कर रहा हूं।

जैसा कि यहाँ कहा गया है :

चूंकि तालिका प्रदर्शन के लिए अनुकूलन करती है, इसलिए यह स्वचालित रूप से डेटा सरणी में परिवर्तन की जांच नहीं करेगी। इसके बजाय, जब ऑब्जेक्ट्स को डेटा सरणी पर जोड़ा जाता है, हटाया जाता है या स्थानांतरित किया जाता है, तो आप इसकी रेंडरर () विधि को कॉल करके तालिका की रेंडर की गई अपडेट को ट्रिगर कर सकते हैं।

तो आपको अपने परिवर्तनों को प्रकट करने के लिए बस अपने रिफ्रेश () पद्धति में रेंडररो () को कॉल करना होगा।

एकीकरण के लिए यहाँ देखें ।


1
यदि क्लाइंट पर तालिका डेटा स्रोत को बदल दिया जाता है, तो यह उत्तर वह है जिसे आप शायद ढूंढ रहे हैं। बहुत अच्छा काम करता है!
एल्विन सालदान

यह कोणीय सामग्री 8 के रूप में सही उत्तर है
टॉम

धन्यवाद। लेकिन मुझे किस ऑब्जेक्ट से "रेंडररोज़ ()" कहना चाहिए? क्या यह 'This.datasource' में है?
साक्षी जूथ

19

चूँकि आप उपयोग कर रहे हैं MatPaginator, आपको केवल पेजिनेटर में कोई परिवर्तन करने की आवश्यकता है, इससे डेटा पुनः लोड होता है।

सरल चाल:

this.paginator._changePageSize(this.paginator.pageSize); 

यह पृष्ठ आकार को वर्तमान पृष्ठ आकार में अपडेट करता है, इसलिए मूल रूप से कुछ भी नहीं बदलता है, निजी _emitPageEvent()फ़ंक्शन को छोड़कर , तालिका पुनः लोड करना भी कहा जाता है।


मैंने आपके कोड की कोशिश की और यह काम नहीं करता है (इसका कोई प्रभाव नहीं है)। हालांकि नेक्स्टपेज और फिर पिछलापेज फिर से काम करता है, लेकिन कोई समाधान नहीं है।
अहमद हसन

_changePageSize()सार्वजनिक रूप से सही नहीं है? क्या यह उपयोग करने के लिए सुरक्षित है? के बारे में अधिक stackoverflow.com/questions/59093781/...
जोन्स

9
this.dataSource = new MatTableDataSource<Element>(this.elements);

विशेष पंक्ति को जोड़ने या हटाने की अपनी कार्रवाई के नीचे इस पंक्ति को जोड़ें।

refresh() {
  this.authService.getAuthenticatedUser().subscribe((res) => {
    this.user = new MatTableDataSource<Element>(res);   
  });
}

this.elements क्या है
पर्वत

8

ऐसा करने का सबसे अच्छा तरीका है कि आप अपने डेटासोर्स कार्यान्वयन के लिए एक अतिरिक्त अवलोकन जोड़ सकते हैं।

कनेक्ट विधि में आप पहले से ही Observable.mergeवेधशालाओं की एक सरणी की सदस्यता लेने के लिए उपयोग कर रहे हैं जिसमें paginator.page, Sort.sortChange, आदि शामिल हैं। आप इसमें एक नया विषय जोड़ सकते हैं और जब आपको रिफ्रेश करने की आवश्यकता होती है तो इसके आगे कॉल कर सकते हैं।

कुछ इस तरह:

export class LanguageDataSource extends DataSource<any> {

    recordChange$ = new Subject();

    constructor(private languages) {
      super();
    }

    connect(): Observable<any> {

      const changes = [
        this.recordChange$
      ];

      return Observable.merge(...changes)
        .switchMap(() => return Observable.of(this.languages));
    }

    disconnect() {
      // No-op
    }
}

और फिर आप recordChange$.next()रिफ्रेश करने के लिए कॉल कर सकते हैं ।

स्वाभाविक रूप से मैं कॉल को रिफ्रेश () विधि में लपेटता हूँ और इसे डेटासोर्स के उदाहरण w / घटक में बंद करता हूँ, और अन्य उचित तकनीकें।


यह तरीका सही तरीका हो सकता है। यह मेरे लिए ठीक है
मनु

जब मैं MatTableDataSource का विस्तार करना चाहता हूं तो मैं इसे कैसे लागू करूं? जब मैं आपके कोड उदाहरण की कोशिश करता हूं तो मुझे त्रुटि मिलती हैProperty 'connect' in type 'customDataSource<T>' is not assignable to the same property in base type 'MatTableDataSource<T>'. Type '() => Observable<any>' is not assignable to type '() => BehaviorSubject<T[]>'. Type 'Observable<any>' is not assignable to type 'BehaviorSubject<T[]>'. Property '_value' is missing in type 'Observable<any>'.
मौरिस

1
@ टाइप करें MatTableDataSource एक अलग रिटर्न प्रकार के साथ कनेक्ट विधि को लागू करता है। यह BehaviorSubject <t []> का उपयोग करता है, जिसका अर्थ है कि आपको अवलोकन के बजाय इसे वापस करने के लिए उदाहरण बदलने की आवश्यकता है। आपको अभी भी DataSource का उपयोग करने में सक्षम होना चाहिए, लेकिन अगर आपको MatTableDataSource का उपयोग करना है तो एक BehaviorSubject लौटें जो आपके अवलोकन योग्य सदस्यता लिया है, यह मानते हुए कि आपके पास शुरू करने के लिए एक है। उम्मीद है की वो मदद करदे। आप नए डेटा स्रोत प्रकार के सटीक सिंटैक्स के लिए MatTableDataSource के लिए स्रोत का उल्लेख कर सकते हैं: github.com/angular/material2/blob/master/src/lib/table/…
jogi

7

आप केवल डेटा स्रोत कनेक्ट फ़ंक्शन का उपयोग कर सकते हैं

this.datasource.connect().next(data);

इस तरह। 'डेटा' डेटाेबल के लिए नए मूल्य हैं


क्षमता थी, लेकिन काम करने के लिए प्रतीत नहीं होता है। यदि उसके बाद आप इस.datasource.data का उपयोग करते हैं, तो इसका अद्यतन नहीं किया गया है।
रुई मार्केज़

4

आप "संक्षिप्त" का उपयोग करके तालिका के डेटा को आसानी से अपडेट कर सकते हैं:

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

language.component.ts

teachDS: any[] = [];

language.component.html

<table mat-table [dataSource]="teachDS" class="list">

और, जब आप डेटा अपडेट करते हैं (language.component.ts):

addItem() {
    // newItem is the object added to the list using a form or other way
    this.teachDS = this.teachDS.concat([newItem]);
 }

जब आप "कॉनकट" का उपयोग कर रहे हैं तो कोणीय वस्तु के परिवर्तन का पता लगाते हैं (यह। टीडीएसडीएस) और आपको दूसरी चीज़ का उपयोग करने की आवश्यकता नहीं है।

पीडी: यह मेरे लिए कोणीय 6 और 7 में काम करता है, मैंने दूसरे संस्करण की कोशिश नहीं की।


2
हां, यह मेरे लिए काम करता है, संदर्भ और मूल्य संस्करण के बारे में एक समस्या है, परिवर्तन का पता लगाने से नए परिवर्तन नहीं दिखते हैं, इसके लिए आपको इसे अपडेट करने की आवश्यकता है।
मायरा रोड्रिग्ज

यह तब काम कर सकता है जब डेटा स्रोत सिर्फ एक सरणी है, लेकिन डेटा स्रोत एक MatTableDataSource ऑब्जेक्ट है जब नहीं।
रुई मरकज़


3

खैर, मैं एक ऐसी ही समस्या में भाग गया, जहाँ मैंने डेटा स्रोत में कुछ जोड़ा और यह पुनः लोड नहीं हो रहा है।

सबसे आसान तरीका है कि मुझे डेटा को पुन: प्रस्तुत करने के लिए बस whas मिला

let dataSource = ['a','b','c']
dataSource.push('d')
let cloned = dataSource.slice()
// OR IN ES6 // let cloned = [...dataSource]
dataSource = cloned

उत्तम!! यह wokrs !! धन्यवाद :)
निकोलस

3

कोणीय 9 में, रहस्य है this.dataSource.data = this.dataSource.data;

उदाहरण:

import { MatTableDataSource } from '@angular/material/table';

dataSource: MatTableDataSource<MyObject>;

refresh(): void {
    this.applySomeModif();
    // Do what you want with dataSource

    this.dataSource.data = this.dataSource.data;
}

applySomeModif(): void {
    // add some data
    this.dataSource.data.push(new MyObject());
    // delete index number 4
    this.dataSource.data.splice(4, 0);
}

2

मैंने दो संसाधनों का उपयोग करके एक अच्छा समाधान प्राप्त किया:

डेटा स्रोत और पेजिनेटर दोनों को ताज़ा करना:

this.dataSource.data = this.users;
this.dataSource.connect().next(this.users);
this.paginator._changePageSize(this.paginator.pageSize);

जहाँ उदाहरण के लिए डेटा स्रोत यहाँ परिभाषित किया गया है:

    users: User[];
    ...
    dataSource = new MatTableDataSource(this.users);
    ...
    this.dataSource.paginator = this.paginator;
    ...

1
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';

export class LanguageComponent implemnts OnInit {
  displayedColumns = ['name', 'native', 'code', 'leavel'];
  user: any;
  private update = new Subject<void>();
  update$ = this.update.asObservable();

  constructor(private authService: AuthService, private dialog: MatDialog) {}

   ngOnInit() {
     this.update$.subscribe(() => { this.refresh()});
   }

   setUpdate() {
     this.update.next();
   }

   add() {
     this.dialog.open(LanguageAddComponent, {
     data: { user: this.user },
   }).afterClosed().subscribe(result => {
     this.setUpdate();
   });
 }

 refresh() {
   this.authService.getAuthenticatedUser().subscribe((res) => {
     this.user = res;
     this.teachDS = new LanguageDataSource(this.user.profile.languages.teach);   
    });
  }
}

8
कृपया अपने उत्तर में एक स्पष्टीकरण जोड़ें, बस पोस्टिंग कोड बहुत उपयोगी नहीं है और इसके परिणामस्वरूप आपका उत्तर हटा दिया जा सकता है।
टीजे वोल्सचॉन

1

मेरे मामले में (कोणीय 6+), मुझे MatTableDataSourceबनाने से विरासत में मिला MyDataSourceबिना कॉल किएthis.data = someArray

this.entitiesSubject.next(this.data as T[])

डेटा जहां प्रदर्शित नहीं है

वर्ग MyDataSource

export class MyDataSource<T extends WhateverYouWant> extends MatTableDataSource<T> {

    private entitiesSubject = new BehaviorSubject<T[]>([]);


    loadDataSourceData(someArray: T[]){
        this.data = someArray //whenever it comes from an API asyncronously or not
        this.entitiesSubject.next(this.data as T[])// Otherwise data not displayed
    }

    public connect(): BehaviorSubject<T[]> {
        return this.entitiesSubject
    }

}//end Class 

1

इसे करने के दो तरीके हैं क्योंकि कोणीय सामग्री असंगत है, और यह बहुत खराब दस्तावेज है। एक नई पंक्ति आने पर कोणीय सामग्री तालिका अपडेट नहीं होगी। हैरानी की बात यह है कि यह प्रदर्शन के मुद्दों के कारण है। लेकिन यह डिजाइन के मुद्दे की तरह दिखता है, वे बदल नहीं सकते हैं। नई पंक्ति होने पर तालिका को अद्यतन करने की अपेक्षा की जानी चाहिए। यदि यह व्यवहार डिफ़ॉल्ट रूप से सक्षम नहीं होना चाहिए, तो इसे बंद करने के लिए एक स्विच होना चाहिए।

वैसे भी, हम कोणीय सामग्री को बदल नहीं सकते हैं। लेकिन हम मूल रूप से इसे करने के लिए एक बहुत खराब दस्तावेज विधि का उपयोग कर सकते हैं:

एक - यदि आप किसी सरणी को सीधे स्रोत के रूप में उपयोग करते हैं:

call table.renderRows()

जहाँ तालिका चटाई की दृश्यदर्शी है

दूसरा - यदि आप छँटाई और अन्य सुविधाओं का उपयोग करते हैं

table.renderRows () आश्चर्यजनक रूप से काम नहीं करेगा। क्योंकि यहाँ चटाई-मेज असंगत है। स्रोत को बदलने के लिए आपको हैक का उपयोग करने की आवश्यकता है। आप इसे इस विधि से करें:

this.dataSource.data = yourDataSource;

जहाँ डेटा स्रोत MatTableDataSource आवरण छँटाई और अन्य सुविधाओं के लिए उपयोग किया जाता है।


0

यह मेरे लिए काम किया:

refreshTableSorce() {
    this.dataSource = new MatTableDataSource<Element>(this.newSource);
}

आदर्श समाधान नहीं है क्योंकि यह तालिका के लिए स्रोत को फिर से बनाता है। और इसे सुव्यवस्थित / सॉकेट के साथ उपयोग करना एक कुशल नहीं है।
मैहान निजत

0

मुझे लगता है कि MatTableDataSourceऑब्जेक्ट किसी तरह से डेटा सरणी से जुड़ा हुआ है जिसे आप MatTableDataSourceकंस्ट्रक्टर के पास भेजते हैं।

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

dataTable: string[];
tableDS: MatTableDataSource<string>;

ngOnInit(){
   // here your pass dataTable to the dataSource
   this.tableDS = new MatTableDataSource(this.dataTable); 
}

इसलिए, जब आपको डेटा बदलना होगा; मूल सूची dataTableमें परिवर्तन और फिर कॉल _updateChangeSubscription()विधि द्वारा तालिका में परिवर्तन को प्रतिबिंबित करें tableDS

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

this.dataTable.push('testing');
this.tableDS._updateChangeSubscription();

वह मेरे साथ कोणीय 6 के माध्यम से काम कर रहा है।


4
यह विधि एक अंडरस्कोर के साथ उपसर्ग है _और आप इसे कहते हैं?
स्टीफन

0

यह मेरे लिए काम कर रहा है:

dataSource = new MatTableDataSource<Dict>([]);
    public search() {
        let url = `${Constants.API.COMMON}/dicts?page=${this.page.number}&` + 
        (this.name == '' ? '' : `name_like=${this.name}`);
    this._http.get<Dict>(url).subscribe((data)=> {
    // this.dataSource = data['_embedded'].dicts;
    this.dataSource.data =  data['_embedded'].dicts;
    this.page = data['page'];
    this.resetSelection();
  });
}

तो आप अपने डेटा स्रोत उदाहरण के रूप में घोषित करना चाहिए MatTableDataSource


0

मैंने कुछ और शोध किया और मुझे यह जगह मिली कि मुझे क्या चाहिए - सर्वर से रिफ्रेश होने पर डेटा को अपडेट करने के लिए क्लीन और रिलेटेड महसूस होता है: https://blog.angular-university.io/angular-material-data-table/

सबसे ऊपर पृष्ठ का श्रेय। नीचे एक नमूना है कि कैसे चयन के परिवर्तन पर डेटा स्रोत के लिए बाध्य एक चटाई-तालिका को अद्यतन करने के लिए एक चटाई-चयनकर्ता का उपयोग किया जा सकता है। मैं कोणीय 7 का उपयोग कर रहा हूं। व्यापक होने के लिए क्षमा करें, पूर्ण होने की कोशिश कर रहा हूं, लेकिन संक्षिप्त रूप में - मैंने यथासंभव कई गैर-आवश्यक भागों को चीर दिया है। इस उम्मीद के साथ कि कोई और तेजी से आगे बढ़ने में मदद करे!

organization.model.ts:

export class Organization {
    id: number;
    name: String;
}

organization.service.ts:

import { Observable, empty } from 'rxjs';
import { of } from 'rxjs';

import { Organization } from './organization.model';

export class OrganizationService {
  getConstantOrganizations(filter: String): Observable<Organization[]> {
    if (filter === "All") {
      let Organizations: Organization[] = [
        { id: 1234, name: 'Some data' }
      ];
      return of(Organizations);
     } else {
       let Organizations: Organization[] = [
         { id: 5678, name: 'Some other data' }
       ];
     return of(Organizations);
  }

  // ...just a sample, other filterings would go here - and of course data instead fetched from server.
}

organizationdatasource.model.ts:

import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { Observable, BehaviorSubject, of } from 'rxjs';
import { catchError, finalize } from "rxjs/operators";

import { OrganizationService } from './organization.service';
import { Organization } from './organization.model';

export class OrganizationDataSource extends DataSource<Organization> {
  private organizationsSubject = new BehaviorSubject<Organization[]>([]);

  private loadingSubject = new BehaviorSubject<boolean>(false);

  public loading$ = this.loadingSubject.asObservable();

  constructor(private organizationService: OrganizationService, ) {
    super();
  }

  loadOrganizations(filter: String) {
    this.loadingSubject.next(true);

    return this.organizationService.getOrganizations(filter).pipe(
      catchError(() => of([])),
      finalize(() => this.loadingSubject.next(false))
    ).subscribe(organization => this.organizationsSubject.next(organization));
  }

  connect(collectionViewer: CollectionViewer): Observable<Organization[]> {
    return this.organizationsSubject.asObservable();
  }

  disconnect(collectionViewer: CollectionViewer): void {
    this.organizationsSubject.complete();
    this.loadingSubject.complete();
  }
}

organizations.component.html:

<div class="spinner-container" *ngIf="organizationDataSource.loading$ | async">
    <mat-spinner></mat-spinner>
</div>

<div>
  <form [formGroup]="formGroup">
    <mat-form-field fxAuto>
      <div fxLayout="row">
        <mat-select formControlName="organizationSelectionControl" (selectionChange)="updateOrganizationSelection()">
          <mat-option *ngFor="let organizationSelectionAlternative of organizationSelectionAlternatives"
            [value]="organizationSelectionAlternative">
            {{organizationSelectionAlternative.name}}
          </mat-option>
        </mat-select>
      </div>
    </mat-form-field>
  </form>
</div>

<mat-table fxLayout="column" [dataSource]="organizationDataSource">
  <ng-container matColumnDef="name">
    <mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
    <mat-cell *matCellDef="let organization">{{organization.name}}</mat-cell>
  </ng-container>

  <ng-container matColumnDef="number">
    <mat-header-cell *matHeaderCellDef>Number</mat-header-cell>
    <mat-cell *matCellDef="let organization">{{organization.number}}</mat-cell>
  </ng-container>

  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
</mat-table>

organizations.component.scss:

.spinner-container {
    height: 360px;
    width: 390px;
    position: fixed;
}

organization.component.ts:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { Observable } from 'rxjs';

import { OrganizationService } from './organization.service';
import { Organization } from './organization.model';
import { OrganizationDataSource } from './organizationdatasource.model';

@Component({
  selector: 'organizations',
  templateUrl: './organizations.component.html',
  styleUrls: ['./organizations.component.scss']
})
export class OrganizationsComponent implements OnInit {
  public displayedColumns: string[];
  public organizationDataSource: OrganizationDataSource;
  public formGroup: FormGroup;

  public organizationSelectionAlternatives = [{
    id: 1,
    name: 'All'
  }, {
    id: 2,
    name: 'With organization update requests'
  }, {
    id: 3,
    name: 'With contact update requests'
  }, {
    id: 4,
    name: 'With order requests'
  }]

  constructor(
    private formBuilder: FormBuilder,
    private organizationService: OrganizationService) { }

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      'organizationSelectionControl': []
    })

    const toSelect = this.organizationSelectionAlternatives.find(c => c.id == 1);
    this.formGroup.get('organizationSelectionControl').setValue(toSelect);

    this.organizationDataSource = new OrganizationDataSource(this.organizationService);
    this.displayedColumns = ['name', 'number' ];
    this.updateOrganizationSelection();
  }

  updateOrganizationSelection() {
    this.organizationDataSource.loadOrganizations(this.formGroup.get('organizationSelectionControl').value.name);
  }
}

0

सामग्री तालिका पढ़ने के बाद पोस्ट डेटा अपडेट को अपडेट नहीं करने पर # 11638 बग रिपोर्ट मुझे सबसे अच्छी लगी (पढ़ें, सबसे आसान समाधान) जैसा कि अंतिम टिप्पणीकार 'श्डहार्मेन' ने एक EventEmitter का उपयोग करने के सुझाव के साथ सुझाया था।

इसमें उत्पन्न डेटा स्रोत वर्ग में कुछ सरल परिवर्तन शामिल हैं

यानी) अपने डेटा स्रोत वर्ग में एक नया निजी चर जोड़ें

import { EventEmitter } from '@angular/core';
...
private tableDataUpdated = new EventEmitter<any>();

और जहां मैं नए डेटा को आंतरिक सरणी (this.data) पर धकेलता हूं, मैं एक ईवेंट का उत्सर्जन करता हूं।

public addRow(row:myRowInterface) {
    this.data.push(row);
    this.tableDataUpdated.emit();
}

और अंत में, 'dataMutation' ऐरे को 'कनेक्ट' विधि में बदलें - निम्नानुसार

const dataMutations = [
    this.tableDataUpdated,
    this.paginator.page,
    this.sort.sortChange
];

0

// यह डेटा
स्रोत है। यह = = [];

this.guests.push ({आईडी: 1, नाम: 'रिकार्डो'});

// डेटा को रिफ्रेश करें। this.guests = Array.from (this.guest);


0
npm install @matheo/datasource

मैंने भविष्य में किसी भी तरह के इनपुट स्ट्रीम (सॉर्ट, पेजिनेशन, फिल्टर्स), और डिबगिंग के साथ कुछ कॉन्फ़िगरेशन का समर्थन करते हुए यह देखने के लिए कि यह कैसे काम करता है, यह देखने के लिए एक आधिकारिक सामग्री डेटा स्रोत होने के लिए एक लाइब्रेरी जारी की।

import { MatDataSourceModule } from '@matheo/datasource';

आप StackBlitz डेमो और आगे की जानकारी यहाँ पा सकते हैं:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6

मुझे आपकी राय सुनने और यदि आवश्यक हो तो अपने उपयोग के मामलों का समर्थन करने में खुशी होगी।
हैप्पी कोडिंग!


0

मैंने ChangeDetectorRef, Subject और BehaviourSubject की कोशिश की थी लेकिन मेरे लिए क्या काम करता है

dataSource = [];
this.dataSource = [];
 setTimeout(() =>{
     this.dataSource = this.tableData[data];
 },200)

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