Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ng2: Equivalent of require

In angular 1.x, we could reference the parent controller by requiring this inside a directive. However, with the whole naming switch-over in angular 2, I cannot really seem to find an equivalent of that functionality?

Things I have tried so far:

  • One way that I see is to @input the parent into the child, but that seems a little bit much.
  • Another way that I saw was using services, but this gave me certain fear, as, to my knowledge, a service is still a singleton, so other components could now mess up stuff on a child of a different component (if that child referenced the service)...
  • Last it was using these local variable thingies (the ones with a hashtag) but that just looked kind of the same as the first option with the input.
like image 728
Xabre Avatar asked Jun 02 '16 21:06

Xabre


1 Answers

I don't know Angular1 well therefore I can't tell what require does exactly or for what purposes it is used.

To the bullets mentioned in your question:

  • Normally you use template binding to wire up parent and children

parent template

<child [childInput]="parentValue" (childOutput)="doSomethingInParent()">
  • Services are singletons per provider. The same provider will always return the same instance but you can provide the same service multiple times and then it's not a real singleton anymore. Therefore, where you provide a service defines the scope of where it is treated as singleton. When you provide it at a component, this component instance and all child components will get the same instance (as long as not a child provides the same type).

This DI behavior prevents conflicts like you mentioned in your question.

  • template variables are rather used to refer to siblings
<child1 [child1Input]="child2.child2Prop" 
    (child1Output)="child2doSomethingInChild2()">
<child2 #child2></child2>
  • If you know the type of the parent component, you can require it to be injected to the constructor of the child component
constructor(@Host() private parent:ParentComponent) {}

This might especially be handy in recursive components (like tree) where it's know what the parent is. In this case additional decorators might be necessary

constructor(@Optional() @SkipSelf() @Host() private parent:ParentComponent) {}

Where

  • @Optional() is for the root component to avoid an exception because there is no parent of the same type to be injected
  • @SkipSelf() avoids the component itself to get injected when it's the same type as the parent it actually wants to get injected. DI always starts on the component itself to look up providers.

See also Inject parent component of the same type as child component

like image 54
Günter Zöchbauer Avatar answered Oct 13 '22 16:10

Günter Zöchbauer