2017-01-10 8 views
0

Я работаю над функциональностью, где мне нужно добавить компонент рекурсивно, и мне нужно событие, которое будет инициировано вложенным компонентом на любом уровне, но оно будет обработано на Main который добавил, что компонентКак обработать событие в рекурсивном вложенном компоненте в angular2

родительский компонент (appcomponent), где мой рекурсивно добавляя WTS комп HTML

<div class="panel panel-default panel-body" *ngIf="rules"> 
     <button class="btn btn-primary" (click)="addRule()">add rule</button> 
     <button class="btn btn-primary" (click)="addGroup()">add group</button> 
     <button class="btn btn-danger" (click)="removeGroup()" *ngIf="enableRemoveGroup">remove group</button> 
     <div *ngIf="rules.groups"> 
<!-- adding itself if there is group --> 
      <wts *ngFor="let group of rules.groups" [data]="group"></wts> 
     </div> 
     <rule *ngFor="let rule of rules.rules" [rule]="rule"></rule> 
    </div> 

WTS компонент .ts

@Component({ 
    selector: 'wts', 
    templateUrl: './wts.component.html', 
    providers: [WtsServiceService], 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class WTSComponent implements OnInit { 
    rules: Group; 
    enableRemoveGroup: boolean = false; 
    @Output() removeGroupCB = new EventEmitter(); 
    @Input('data') 
    set data(value) { 
     if (value) { 
      this.enableRemoveGroup = true; 
     } 
     this.rules = value || new Group(); 
    }; 
    constructor(private wtsServiceService: WtsServiceService) { 
     this.rules = new Group(); 
    } 
    private addGroup() { 
     if (!this.rules.groups) { 
      this.rules.groups = []; 
     } 
     this.rules.groups.push(new Group()); 
     console.log(this.rules); 
    } 
    private removeGroup() { 
     delete this.rules; 
    } 
    private addRule() { 
     this.rules.rules.push(new Rule()); 
    } 
    ngOnInit() { } 
} 

В моем компе у меня есть объект правил, которые содержат правила и группу, и группа содержит правило и группу

вот моя модель

export class Rule { 
    subjectType: string; 
    valueType: string; 
    subject: string; 
    value: string; 
    constructor(st = '', vt = '', s = '', v = '') { 
     this.subjectType = st; 
     this.valueType = vt; 
     this.subject = s; 
     this.value = v; 
    } 
} 
export class Group { 
    rules: Rule[]; 
    groups: Group[]; 
    constructor() { 
     this.rules = []; 
     this.rules.push(new Rule()); 
    } 
}; 

Если мы имеем группу жгуты группы то он вложил себя в состав пользовательского интерфейса. и у нас есть компонент правила в список правил

здесь мои правила аккомпанемента .ts

@Component({ 
    selector: 'rule', 
    templateUrl: './rule.component.html', 
    styleUrls: ['./rule.component.css'], 
    providers: [WtsServiceService], 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class RuleComponent implements OnInit { 
    rule: Rule; 
    @Input('rule') 
    set Setrule(value) { 
    this.rule = value; 
    } 
    constructor(private wtsServiceService: WtsServiceService) { } 

    private triggerHanlder() { 
    this.wtsServiceService.triggerCallBack();// to trigger appcomponent function 
    } 
} 

вот мое правило комп .html

<p *ngIf="rule"> 
    <button class="btn btn-danger" (click)="triggerHanlder()">trigger handler</button> 
</p> 

который будет инициировать событие, когда пользователь выбирает действительный правило и обрабатывать основной компонент, т. е. appcomponent

Для этого я создал службу, которая возвращает наблюдаемый, который я s подписались на компонент appcomponent и rule, вызывают функцию для запуска этого события, но теперь он работает как ожидалось.

вот моя служба

@Injectable() 
export class WtsServiceService { 
    resultSubject: ReplaySubject<any> = new ReplaySubject(1); 
    constructor() { } 
    public handleCallBack() { 
    return this.resultSubject; 
    } 
    public triggerCallBack() { 
    this.resultSubject.next({}); 
    } 
} 

вот мой appcomponent

export class AppComponent { 
    constructor(private _wtsServiceService: WtsServiceService) { 

    } 
    ngOnInit() { 
    this._wtsServiceService.handleCallBack().subscribe(() => { 
     console.log('parent function');//this should get execute when user click on trigger handler on rule comp 
    }) 
    } 
} 

appcomp> WTS> WTS> WTS> ...> правило (здесь я должен испускать событие и должно это правило compo может на любом уровне)

Пожалуйста, помогите найти обходной путь и предложите, есть ли другой лучший подход.

ответ

1

Я хотел бы сделать компонент корневого wts другой компонент root-wts (может иметь один и тот же шаблон, как вложенной wts компонента, предоставляют услугу, которая вводится в каждом wts и rule, а также root-wts.

root-wts выписывает наблюдаемой в этой услуге wts (если применимо) и rule выделяют события с использованием наблюдаемой в общей службе

+0

да, то же самое я и пытаюсь сделать, но не работает для меня, я назвал Функция triggerCallBack службы из правила comp и подписаться handleCallBack на app comp – Rhushikesh

+0

Я думаю, проблема в том, что вы предоставляете сервис для каждого компонента, и поэтому вы получаете столько экземпляров службы, сколько экземпляров компонентов. Вы должны предоставить его только один раз на компоненте, который создается только один раз или на модуле (чтобы сделать его единственным одноточечным). –

+1

Привет, спасибо за работу – Rhushikesh