Difference between @Self and @Host Angular 2+ Decorators for dependency injection

Please explain the difference between @Selfand @Host.

The angular API documentation gives some insight. But this is not clear to me. The example presented for Selfis used ReflectiveInjectorto illustrate use.

However, it could rarely be used ReflectiveInjectorin the actual application code (perhaps more in testing). Can you give an example of where you would use @Self instead of @Host outside such test scripts

+6
source share
2 answers

TL; DR

, @Self, Angular , , /.

, @Host, Angular , , /, . Angular "host".

, @Self @Host , ( ).

, Angular , , , , Angular .

, @Host , ", - ", , , .

@Self ()

class Dependency {}

@Injectable()
class NeedsDependency {
  constructor(@Self() public dependency: Dependency) {}
}

let inj = ReflectiveInjector.resolveAndCreate([Dependency, NeedsDependency]);
const nd = inj.get(NeedsDependency);

expect(nd.dependency instanceof Dependency).toBe(true);

inj = ReflectiveInjector.resolveAndCreate([Dependency]);
const child = inj.resolveAndCreateChild([NeedsDependency]);
expect(() => child.get(NeedsDependency)).toThrowError();

@Host ()

class OtherService {}
class HostService {}

@Directive({selector: 'child-directive'})
class ChildDirective {
  logs: string[] = [];

  constructor(@Optional() @Host() os: OtherService, @Optional() @Host() hs: HostService) {
    // os is null: true
    this.logs.push(`os is null: ${os === null}`);
    // hs is an instance of HostService: true
    this.logs.push(`hs is an instance of HostService: ${hs instanceof HostService}`);
  }
}

@Component({
  selector: 'parent-cmp',
  viewProviders: [HostService],
  template: '<child-directive></child-directive>',
})
class ParentCmp {
}

@Component({
  selector: 'app',
  viewProviders: [OtherService],
  template: '<parent-cmp></parent-cmp>',
})
class App {
}

@Self

, , ; , .

, providers . , , .

, , - . , @Self, Angular, , .

+9

https://netbasal.com/exploring-the-various-decorators-in-angular-b208875b207c

:

@Host - @Host DI ,

:

@Self - @Self DI ,

:

https://plnkr.co/edit/UmpPTnzcRxgDc9Hn5I9G?p=preview

, MyDir : @Self '@Host Garage dependency @Optional @Host Sun, , . Host - null

:

 parent component. 
  { "type": "child garage", 
    "car": { "model": "child car" }, 
    "sun": null 
  }

:

  class Garage {
    car;
    type;
    sun;

    constructor(type) {
      this.type=type;
    }
    setCar(car) {
      this.car = car;
    }
    setSun(sun) {
      this.sun = sun;
    }
  }

  class Car {
    model;
    constructor(model) {
      this.model=model;
    }
  }

  class Sun { }

  @Directive({
    selector: '[myDir]',
    providers:[
      {provide: Car, useValue: new Car('child car')}
      {provide: Garage, useValue: new Garage('child garage')}
    ]
  })
  export class MyDir {
    constructor(@Self() private car: Car, @Host() private garage: Garage,
      @Optional() @Host() private sun: Sun) {
       this.garage.setCar(this.car);
       this.garage.setSun(this.sun);
    }
  }

  @Component({
    selector: 'parent',
    template: `
       parent component. {{garage|json}}
    `,
    providers:[
      {provide: Car, useValue: new Car('parent car')},
      {provide: Garage, useValue: new Garage('parent garage')}
    ]
  })
  export class Parent {
    childDep;
    constructor(private car: Car, private garage: Garage) {
    }
  }

  @Component({
    selector: 'my-app',
    template: `
  <parent myDir></parent>
    `,
    providers:[
      {provide: Car, useValue: new Car('app car')},
      {provide: Garage, useValue: new Garage('app garage')},
      {provide: Sun, useValue: 'sun'}
    ]
  })
  export class App {
  }
+2

Source: https://habr.com/ru/post/1016920/


All Articles