Как мне удалить это для цикла и использовать вместо него функцию array.some? - PullRequest
0 голосов
/ 10 октября 2019

У меня есть следующий класс. Я хотел бы преобразовать функцию filterOutEmails для использования array.some вместо текущего кода.

export class UsertableComponent {
  dataSource: MatTableDataSource<TrialUser>;


  createTableFromServer = (data: TrialUsers[], emailDomains:string) => {
    this.dataSource = new MatTableDataSource(data);
    this.dataSource.filterPredicate = this.filterOutEmails
  } 

  filterOutEmails = (row: TrialUser, emailDomains: string): boolean => {
    const listofFilters = emailDomains.split(',');
    for (let i = 0; i < listofFilters.length; i++){
      if (row.email.toLowerCase().includes(listofFilters[i].trim())){
        return true;
      };
    }
    return false;
  }
}

Я попытался сделать следующее, но он дал this, когда я пытался использоватьФункция стрелки, я не мог пройти в ряду. (Если я не установил this: TrialUser в качестве параметра, тогда «this» соответствует Type UsertableComponent, классу, в котором находится функция, даже если я передаю row в some как thisObject)

private determineIfRowShouldBeShown(this: TrialUser, domain: string): boolean {
  const row: TrialUser = this;
  return !row.email.toLowerCase().includes(domain.trim());
}

private filterOutEmails= (row: TrialUser, emailDomains: string): boolean {
  const listofFilters = emailDomains.split(',');
    return listofFilters.some(this.determineIfRowShouldBeShown, row) ;
  }
}

Установка 'defineIfRowSHouldBeShown' в качестве встроенной функции жирной стрелки работает, но я хотел бы оставить определение функции отдельным.

1 Ответ

2 голосов
/ 11 октября 2019

Если вы используете функцию стрелки, this становится лексически связанным, даже когда передается в качестве аргумента:

// If you're gonna abuse `this` I wouldn't put the function in a class as it's really confusing for `this` to not be the instance. You also can't use arrow functions in this case as they prevent rebinding the context.
function determineIfRowShouldBeShown(domain: string): boolean {
    return !this.email.toLowerCase().includes(domain.trim());
}

export class UsertableComponent {
  dataSource: MatTableDataSource<TrialUser>;

  createTableFromServer = (data: TrialUsers[], emailDomains:string) => {
      this.dataSource =  new MatTableDataSource(data);
      this.dataSource.filterPredicate = this.filterOutEmails
  }
  // I don't think this is a good name since it doesn't actually filter anything.
  filterOutEmails(row: TrialUser, emailDomains: string): boolean{
    return emailDomains.split(',').some(determineIfRowShouldBeShown, row);
  }
}

Это можно сделать и несколькими другими способами:

Использование руководствапривязка функции:

...
filterOutEmails(row: TrialUser, emailDomains: string){
  emailDomains.split(',').some(determineIfRowShouldBeShown.bind(row));
}

Использование каррирования / частичного применения (мои предпочтения)

const determineIfRowShouldBeShown = (row: TrialUser) => (domain: string): boolean => !row.email.toLowerCase().includes(domain.trim());
...
filterOutEmails(row: TrialUser, emailDomains: string){
  emailDomains.split(',').some(determineIfRowShouldBeShown(row));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...