0

I am working on functionality where I need to add component recursively and I want an event which will be triggered by the nested component at any level but it get handled on the Main parent component(appcomponent) which added that component

where is my recursively adding wts comp 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 component .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() { }
}

In my comp I have object rules which contain the rules and groups, and group contains rule and group

here is my model

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());
    }
};

If we have group withing group then it nested itself to form the UI. and we have rule component to list rules

here is my rule comp .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
  }
}

here is my rule comp .html

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

which will trigger an event when user select a valid rule and get handled by main component ie appcomponent

To do that I have created on service which returns observable which is subscribed on appcomponent and rule component call a function to trigger that event but its now working as expected.

here is my service

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

here is my 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 >...> rule (here I have to emit an event and should get handled on appcomp. this rule compo may at any level)

Please help to find the workaround and suggest if there is any other better approach.

1 Answer 1

1

I would make the root wts component a different component root-wts (can have the same template as the nested wts component, provide a service that that is injected to every wts and rule and also root-wts.

root-wts subscribes to an observable in this service wts (if applicable) and rule emit events using the observable in the shared service

Sign up to request clarification or add additional context in comments.

11 Comments

yes, same thing I am also trying to do but not working for me I have called triggerCallBack function of service from rule comp and subscribe handleCallBack on app comp
I think the problem is that you provide the service on every component and therefore you get as many service instances as component instances. You should provide it only once on a component that is only instantiated once or on a module (to make it application-wide singleton).
Yes, I think it's fine.
its now working if I added multiple time on same component
Its get trigger all of the component
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.