Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject a parent component into a shared directive without specifying component type?

How can I define my directive for use it in all component :

my directive.ts :

import { Parent } from '../../_common/Parent';
declare var jQuery: any;

@Directive({
  selector: '[icheck]'
})

export class IcheckDirective implements AfterViewInit {

  constructor(private el: ElementRef, private parentCmp: Parent) {
    jQuery(this.el.nativeElement).iCheck({
      checkboxClass: 'icheckbox_square-aero',
      radioClass: 'iradio_square-aero'
    }).on('ifChecked', function(event) {
      if (jQuery('input').attr('type') === 'radio') {
        parentCmp.selectType(jQuery('input[name="filters.type"]:checked').val());
      }
    });
  }
}

my Parent.ts

export abstract class Parent {
 }

My component.ts (using icheck)

 import { Component, OnInit, ViewContainerRef } from '@angular/core';
    import { ActivatedRoute, Router } from '@angular/router';
    import { Parent } from '../../_common/Parent';

    declare var jQuery: any;

    @Component({
      selector: 'app-folders',
      templateUrl: './folders.component.html',
       providers: [{ provide: Parent, useExisting: AdminEditComponent }]
    })
    export class FoldersComponent implements OnInit, Parent {

         name = 'FoldersComponent ';

      constructor(
        private route: ActivatedRoute,
        private router: Router,
      ) {
      }

      ngOnInit() {

      }

      selectType(value: string) {
         console.log(value);
      }
    }

my component.html :

<input type="radio" icheck checked> => here how can I define an event for calling method **selectType** ?

Here, we can see that I use the component in param FoldersComponent, so when I want to use this directive (icheck) in other component (like AppComponent), I got error .. How can I do for make it global for all component .. NB : In folderComponent I define method selectType called when I select a button radio

like image 452
user1814879 Avatar asked Jun 26 '17 13:06

user1814879


1 Answers

Because Angular modules support components/directives/pipes encapsulation you need to use a pattern called shared modules. Create a module and put your directive into the declarations of the shared module and then import that module into every module with components that use this directive. Here is the documentation on shared module.

EDIT:

As I understand, you want to be able to use icheck directive with any component and not hardcode type of parent component here private parentCmp: FoldersComponent. This can be done in the following way:

1) Define a token that will be used for parent injection. It can be a simple class like this:

export abstract class Parent { }

2) Define a provider on the component that will be used alongside icheck:

@Component({
   providers: [{ provide: Parent, useExisting: AnyComponent }]
})
export class AnyComponent implements Parent {
   name = 'AnyComponent';
}

3) Use this token inside icheck:

export class IcheckDirective implements AfterViewInit {
  constructor(private el: ElementRef, @Optional() private parentCmp: Parent) {

Here is the plunker

like image 175
Max Koretskyi Avatar answered Oct 13 '22 01:10

Max Koretskyi