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




angular-material refresh (13)

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

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

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

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

मैं एक सेवा से उपयोगकर्ता डेटा प्राप्त करके और ताज़ा विधि में एक डेटा स्रोत में पास करके डेटास्टोर को इनिशियलाइज़ करता हूँ।

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
  }

}

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


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

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

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

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

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


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

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

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

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

एकीकरण के लिए here देखें।


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

कनेक्ट विधि में आपको पहले से ही वेधशालाओं का उपयोग करना चाहिए जो कि वेधशालाओं की एक सरणी की सदस्यता लेने के लिए है जिसमें 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 / घटक में बंद कर दूंगा, और अन्य उचित तकनीक।


ठीक है, मैं एक समान समस्या में भाग गया, जहाँ मैं डेटा स्रोत में कुछ जोड़ रहा हूँ और यह सबसे आसान तरीका नहीं है, जो मुझे पता चला है कि डेटा को फिर से भरने के लिए बस

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

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

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

मुझे लगता है कि MatTableDataSource कंस्ट्रक्टर के पास जाने वाले डेटा ऐरे के साथ MatTableDataSource ऑब्जेक्ट कुछ तरह से जुड़ा हुआ है।

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

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

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

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

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

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

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


मेरे मामले में (कोणीय 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 

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

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

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

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

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 रूप में घोषित करना चाहिए


सामग्री तालिका पढ़ने के बाद पोस्ट डेटा अपडेट को अपडेट नहीं करने पर # 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
];

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

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

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

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




refresh