Angular 2, динамическое создание пользовательского канала на основе предпочтений пользователя.

У меня есть несколько разных каналов, которые я хотел бы включать и выключать, если пользователь хочет фильтровать свои данные по различным критериям. Как мне активировать/деактивировать каналы, используемые в настоящее время в поиске, или создать один канал, который ведет себя по-разному в зависимости от того, на какие кнопки нажал пользователь?

Например, две трубы/фильтра будут выглядеть так...

//cloud.pipe.ts
import {Pipe} from '@angular/core';
import {Hero} from './hero';

@Pipe({
  name: 'Cloud'
})
export class CloudPipe{
  transform(value) {
    if (value == null) {
      return null;
    }
    return value.filter(hero => {
      return hero.cloud === true;
    });
  }
}
//location.pipe.ts
import {Pipe} from '@angular/core';
import {Hero} from './hero';
import { HeroService } from './hero.service';
import { HeroesComponent } from './heroes.component';

@Pipe({
  name: 'Location'
})

export class LocationPipe{
  transform(value) {
    if (value == null) {
      return null;
    }
    return value.filter(hero => {
      return hero.location < 500;
    });
  }
}

Затем я хотел бы, чтобы пользователь переключал разные кнопки фильтра и добавлял/удалял каналы в список. Каков наилучший подход для чего-то подобного?

<!--Toggle what pipes should be used in search-->
<!--For example how can I construct the "updatePipe" function for doing this?-->
<button id="activateCloud" (click)="updatePipe()"></button>
<button id="activateLocation" (click)="updatePipe()"></button>
<!--Is it possible to have: neither of the pipes active, both at the same time or just one at the time? How can I do this?-->
<div *ngFor="let hero of heroes | Cloud | Location ></div> 

Я бы не хотел, чтобы все было в одной трубе, поскольку я хотел бы расширить каждую трубу, чтобы делать больше в будущем. Таким образом, каждая труба должна быть «своей» и работать независимо друг от друга, но в то же время работать в связке с другими трубами, когда это необходимо.


person Anton Scotte    schedule 31.07.2016    source источник


Ответы (1)


Вы можете создать канал-оболочку, который перенаправляется на другие каналы в зависимости от используемых параметров, таких как

<div *ngFor="let hero of heroes | myPipe:'Cloud':'Location'" ></div> 
@Pipe({
  name: 'myPipe'
})
export class MyPipe{
  locationPipe = new LocationPipe();
  cloudPipe = new CloudPipe();
  constructor() {
    pipes = {
      locationPipe: this.locationPipe,
      cloudPipe: this.clouldPipe
    };
  }

  transform(value, param1, param2) {
    var result = value;
    if(pram1) {
      result = this.pipes[param1].transform(result);
    }
    if(pram2) {
      result = this.pipes[param1].transform(result);
    }
  }
}

или если список каналов используется как массив, например

<div *ngFor="let hero of heroes | myPipe:['Cloud':'Location']" ></div> 
@Pipe({
  name: 'myPipe'
})
export class MyPipe{
  locationPipe = new LocationPipe();
  cloudPipe = new CloudPipe();
  constructor() {
    pipes = {
      locationPipe: this.locationPipe,
      cloudPipe: this.clouldPipe
    };
  }

  transform(value, params) {
    var result = value;
    for(var p in params) {
      result = this.pipes[p].transform(result);
    }
  }
}
person Günter Zöchbauer    schedule 31.07.2016
comment
Спасибо за быстрый ответ, это выглядит многообещающе. Я проверю это позже, если я смогу заставить его работать! - person Anton Scotte; 31.07.2016
comment
В вашем примере LocationPipe — единственный канал, который вы экспортируете? (Почему LocationPipe является оболочкой самого себя и cloudPipe?) И что в этом сценарии делает new LocationPipe(); Ссылаться на? Подразумевается ли, что два канала (LocationPipe, CloudPipe) импортируются из отдельных файлов (как в моем примере) и используются для повторного экспорта нового LocationPipe? Извините, но я не очень слежу за тем, что происходит. Также я получаю сообщение об ошибке: свойство «каналы» не существует для типа «LocationPipe» в моем компиляторе машинописного текста. Надеюсь, я не упустил что-то очевидное, не могли бы вы немного подробнее объяснить, что происходит в вашем примере? - person Anton Scotte; 31.07.2016
comment
Извините, забыл переименовать. Я обновил свой ответ. LocationPipe и CloudPipe на самом деле не используются как каналы, а просто вызываются напрямую. Вместо этого они также могут быть внедрены с помощью конструктора. - person Günter Zöchbauer; 01.08.2016