简体   繁体   中英

How do I call a function in a class from another class in Angular 6?

Here's my code:

import { Component, OnInit, ViewChild } from '@angular/core';
import { AuthService } from '../core/auth.service';
import { MatRadioButton, MatPaginator, MatSort, MatTableDataSource } from '@angular/material';
import { SelectionModel } from '@angular/cdk/collections';
import { OrdersService } from '../orders.service';

export interface DataTableItem {
  ordersn: string;
  order_status: string;
  update_time: number;
}

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})

export class HomeComponent implements OnInit {
  radioValue: number;
  dataSource = new UserDataSource(this.orderService);
  selection = new SelectionModel<any>(true, []);

  // Sorting and pagination
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild(MatPaginator) paginator: MatPaginator;

  // Columns displayed in the table. Columns IDs can be added, removed, or reordered.
  displayedColumns = ['ordersn', 'order_status', 'update_time'];

  // Filter
  applyFilter(filterValue: string) {
    this.dataSource.filter = filterValue.trim().toLowerCase();
  }

  // Whether the number of selected elements matches the total number of rows.
  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  }

  // Selects all rows if they are not all selected; otherwise clear selection.
  masterToggle() {
    this.isAllSelected() ?
      this.selection.clear() :
      this.dataSource.data.forEach(row => this.selection.select(row));
  }

  constructor(public auth: AuthService, private orderService: OrdersService) {
  }

  onSelectionChange(radioSelection: MatRadioButton) {
    this.radioValue = radioSelection.value;
    console.log(this.radioValue);
  }

  ngOnInit() {
    this.dataSource.sort = this.sort;
    this.dataSource.paginator = this.paginator;
  }
}

export class UserDataSource extends MatTableDataSource<any> {
  constructor(private orderService: OrdersService) {
    super();

    this.orderService.GetOrdersList().subscribe(d => {
      this.data = d.orders;
    });
  }

  radioFilter() {
    const array = [];

    this.orderService.GetOrdersList().subscribe(d => {
      for (const entry of d.orders) {
        if (entry.order_status === 'READY_TO_SHIP') {
          array.push(entry);
        }
      }

      this.data = array;

      console.log(array);
    });
  }
}

I'm trying to call radioFilter() from HomeComponent . What I've tried:

  • Implementing @ViewChild in HomeComponent but I would get this error: Class 'UserDataSource' used before its declaration .
  • Importing UserDataSource and then added to the constructor in HomeComponent . I would get this error: Getting Uncaught Error: Can't resolve all parameters for HomeComponent

I'm kind of out of anymore idea, thus any suggestion is much appreciated. Thanks!

Getting Uncaught Error: Can't resolve all parameters for HomeComponent

First of all your dataSource is not registered in a ngModule as injectable. So it's not possible to inject it to the constructor in HomeComponent. I also don't think you want to do that because ngMaterial-dataSources are stateful and injectables shouldn't be stateful.

Class 'UserDataSource' used before its declaration

Your dataSource is not a ViewChild in your component's template. It's just an object (without a html-template). The error you get is that annotations in typeScript are processed on compile/transpile time. But the UserDataSource class is declared below the HomeComponent. You are using it before it's declared. You could just put it above the HomeComponent but better put it in a new file and import it. But that's not the solution.

Possible solution

I don't get why you cannot just call the radioFilter method. It's a public method of your UserDataSource and there is an instantiated object in HomeComponent called dataSource. Just make sure to not call it in the constructor. Member variables are processed after the constructor is called. But imho you can just call dataSource.radioFilter()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM