2016-12-22 1 views
1

У меня есть элемент сетки, который я хочу расширить, добавив фильтры в каждый столбец. На самом деле у меня разные типы фильтров для каждого столбца, такие как простой ввод текста, фильтр параметров, фильтр диапазона дат и т. Д. Итак, в настоящее время я хочу создать фабрику фильтров. Я хочу просто указать тип фильтра и получить необходимый компонент фильтра. Я следовал этому guide, и это то, что у меня есть до сих пор.Angular2: получить данные от компонента, созданного с помощью ComponentFactoryResolver

завод компонент:

import { 
    Component, Input, Inject, ViewContainerRef, ViewChild, ReflectiveInjector, ComponentFactoryResolver 
} from '@angular/core'; 
import mod = require('../../env-bootstrap'); 
import {OptionsFilter} from "./options/options.filter"; 
import {BlankFilter} from "./blank/blank.filter"; 

@Component(mod.check({ 
    selector: 'filters-factory', 
    moduleId: module.id, 
    entryComponents: [OptionsFilter, BlankFilter], 
    template: '<div #dynamicComponentContainer></div>' 
})) 

export class FiltersFactory { 
    constructor(@Inject(ComponentFactoryResolver) private resolver: ComponentFactoryResolver) {} 
    currentComponent = null; 

    @ViewChild('dynamicComponentContainer', {read: ViewContainerRef}) dynamicComponentContainer: ViewContainerRef; 

    @Input() set componentData(data: {componentName: any, inputs: any }) { 
     if (! data) { 
      return; 
     } 

     switch (data.componentName) { 
      case 'name': 
       component = OptionsFilter; 
       break; 
      default: 
       component = BlankFilter; 
     } 

     // Inputs need to be in the following format to be resolved properly 
     let inputProviders = Object.keys(data.inputs).map((inputName) => { 
      return {provide: inputName, useValue: data.inputs[inputName]}; 
     }); 
     let resolvedInputs = ReflectiveInjector.resolve(inputProviders); 

     // We create an injector out of the data we want to pass down and this components injector 
     let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicComponentContainer.parentInjector); 

     // We create a factory out of the component we want to create 
     let factory = this.resolver.resolveComponentFactory(component); 

     // We create the component using the factory and the injector 
     let component = factory.create(injector); 

     // We insert the component into the dom container 
     this.dynamicComponentContainer.insert(component.hostView); 

     // Destroy the previously created component 
     if (this.currentComponent) { 
      this.currentComponent.destroy(); 
     } 

     this.currentComponent = component; 
    } 
} 

И мой OptionsFilter компонент:

import {Component, Injector, Inject, Output, EventEmitter } from '@angular/core'; 
import mod = require('../../../env-bootstrap'); 

@Component(mod.check({ 
    selector: 'options-filter', 
    moduleId: module.id, 
    styleUrls: 'share/filters/options/options.css', 
    templateUrl: 'share/filters/options/options.html' 
})) 

export class OptionsFilter { 
    showNum = 0; 
    constructor(@Inject(Injector) private injector: Injector) { 
     this.showNum = this.injector.get('showNum'); 
    } 

    @Output() filterValue = new EventEmitter(); 

    private onChange(option) { 
     this.filterValue.emit(option); 
    } 
} 

Вот как я добавляю заводскую компонент к моей сетке

<td *ngFor="let columnName of columnNames"> 
    <filters-factory [componentData]="{ componentName: columnName ,inputs: { showNum: 9} }"></filters-factory> 
</td> 

И мой FilterOptions шаблон

<select (change)="onChange($event)"> 
    <option disabled>Options</option> 
    <option>33</option> 
    <option>33</option> 
</select> 

Так что теперь для меня главное, чтобы путь option значение от html select тег от OptionsFilter к компоненту фабрики. Является ли это возможным?

ответ

1

В FiltersFactory вы можете получить доступ к полям динамического компонента с использованием

console.log(this.currentComponent.instance.option); 

Для этого нужно свойство option в OptionsFilter, в настоящее время у вас есть только @Output().

Вы не можете использовать привязки с динамически добавленными компонентами, поэтому @Input() и @Output() не имеет смысла.

Вы также всегда можете использовать общий сервис для общения с динамически добавленных компонентов, как объяснено в https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

+0

Я не могу понять, где я должен поместить 'option', мне нужно что-то вроде так <выберите [(ngModel)] = "вариант" класс = "параметры фильтра"> <опция выключена> параметры ? –

+0

Мне немного сложно понять, что вы на самом деле пытаетесь выполнить. Что вы можете сделать, это добавить вход в 'FiltersFactory' и использовать его как' ', а затем в' FiltersFactory' '@Input() set option (value) {this.currentComponent .instance.option = значение;} ' –

+0

В настоящее время я пытаюсь получить выбранное значение из тега html' select' –

Смежные вопросы