6

[UPDATE] Please read the comment history to understand the context.


All:

I am pretty new to angular2, when I follow its quickstart guide, one question confuses me:

I simplify the app.component.ts as:

import { Component } from "angular2/core";
@Component({
    selector: "my-app",
    template: "<div>{{title}}</div>"
})
export class AppComponent {
        title = "Tour of Heroes" + Math.random();
}

And I add another my-app tag into index.html like:

  <body>
    <my-app>Loading...</my-app>
    <my-app>Loading...</my-app>
  </body>

I wonder why the second one can not get rendered?

Another question related to this is:

If I put two instance of same component, each one will keep their own member variable, but if I inject service into one component, then all component instances share the same service instance, I find the only obvious diff is they use different annotation( other than this, they both export a class): @Component and @Injectable, and one in directives array while the other in providers array. I wonder if these 2 annotation tell angular how can treat the instance or the directives array and providers array do that?

1
  • Comments can be deleted, if the comments contain information vital to answering the question, than you should mirror that info into the question. Commented Jun 7, 2017 at 14:48

4 Answers 4

4

Angular2 doesn't allow to bootstrap the same component twice in an HTML page.

This is however possible to bootstrap different application components if you want in a same HTML page.

See this documentation for more details:

Edit

Regarding your second question, you need to be aware that @Component and @Injectable are decorators. They are responsible to "wrap" target instances and allow dependency injections by providing right dependency instances in constructor based on configured metadata.

Regarding hierarchical injectors, you could have a look at this link:

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

9 Comments

Thanks, so this mean only the root app component may have this restriction issue? If I put component inside app component, then everything is ok?
Yes, it's only at the bootstrap level. You can use component like you want inside your Angular2 application ;-)
See the doc for more details: angular.io/docs/ts/latest/api/platform/browser/…. Section "Bootstrapping Multiple Applications".
Components are instantiated according to their use in templates. Services relies on where their providers are configured. For example, if you put a provider when bootstrapping the application, a single instance will be shared by the whole application.
You're welcome! For 1) yes two instances of the service (one per level) For 2) yes only import the class and the same instance will be injected...
|
2

This is currently not supported. You need to initialize each root component with bootstrap(AppComponent) but that only works if both components have different selectors.

See also https://github.com/angular/angular/issues/7136

10 Comments

Yes, it works fine for components inside other components. The root component has also other limitations github.com/angular/angular/issues/1858
Thanks, I wonder how does Angular2 decides when to generate a new one or reuse a existing instance? Is that because if I use @Injectable or use @Componnet?
Angular DI is hierachical. Each component, directive, pipe, ... has its own injector, each child components injector is a child of the injector of the parent component. bootstrap() creates the root injector. When DI looks up a dependency it iterates from the requesting component towards root. When it finds a provider it requests the instance from there. The injector where the provider was found keeps a single instance of the dependency and returns the same every time. If you get a new instance or the same depends where you register a provider.
You update is quite hard to understand. providers on a component is as explained in a previous comment if the component instance gets its own service instance or if one provided by a parent injector is injected. directives is for registering components and directives to be used in the view (HTML). If a directive is registered and a selector matches then Angular creates an instance. Some CORE_DIRECTIVES ngFor, and similar a applied globally and don't need to be added to directives
Angular usually injects services not components. When new instances are created is what I tried to explain above. It depends on where the service is registered as provider. Components and directives are always new instances for each tag that matches the selector.
|
0

I found another post that explains how to implement injecting multiple instances of the same component using the decorator @ViewChildren().

It worked in my case using a custom form component built from the Angular Shared Material Library. Hopefully it will work for you too!

How to treat same component as two different components inside same parent [Angular]

Comments

-1

To my knowledge, apart from the main component you can use any other component multiple times in the same html page.

Can achieve this by using @Input decorator Declare an attribute to your selector element/directive in html and get the value of that attribute in Component by using @Input decorator

import { Component,Input } from "angular2/core";

@Component({
    selector: "my-app",
    template: "<div>{{title}}</div>"
})
export class AppComponent {
        @Input() title;
}    
  <body>
    <my-app title = "somedata1">Loading...</my-app>
    <my-app title = "somedata2">Loading...</my-app>
  </body>

Can find an example in this link

Angular2 .. Using the same component to show different data on the same page depending on service response

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.