Angular2 Exception: No provider for Service

前端 未结 2 1536
庸人自扰
庸人自扰 2020-12-22 08:24

I\'m unable to instantiate my application when I have the component which is nested under the root component providing a component which it uses in it\'s constr

相关标签:
2条回答
  • 2020-12-22 09:06

    You can inject directly the parent component into a component without specifying it into component providers. To do that you need to use component into other ones and set it into the directives attribute:

    @Component({
      selector: 'child',
      template: `
        <div></div>
      `
    })
    export class Child {
      constructor(@Inject(forwardRef(() => App)) parent: App) {
      }
    }
    
    @Component({
      directives: [Child],
      template: `
        Everything rendered fine!
        <child></child>
      `,
      selector: 'app'
    })
    export class App {
      constructor() {
      }
    }
    

    What is a bit strange in your sample is that you didn't define selector and template properties for components Child and GrandChild. Are they really components?

    In your sample, you made things in the wrong way. If you want to get instances of child component from a parent component, you need to leverage the @ViewChild decorator to reference the child component from the parent one by injection:

    import { Component, ViewChild } from 'angular2/core';  
    
    (...)
    
    @Component({
      selector: 'my-app',
      template: `
        <h1>My First Angular 2 App</h1>
        <child></child>
        <button (click)="submit()">Submit</button>
      `,
      directives:[App]
    })
    export class AppComponent { 
      @ViewChild(SearchBar) searchBar:SearchBar;
    
      (...)
    
      someOtherMethod() {
        this.searchBar.someMethod();
      }
    }
    

    Here is the updated plunkr: http://plnkr.co/edit/mrVK2j3hJQ04n8vlXLXt?p=preview.

    You can notice that the @Query parameter decorator could also be used:

    export class AppComponent { 
      constructor(@Query(SearchBar) children:QueryList<SearchBar>) {
        this.childcmp = children.first();
      }
    
      (...)
    }
    

    You can notice that you don't need the @Injectable decorator when you have the @Component one...

    0 讨论(0)
  • 2020-12-22 09:19

    You can fix it by adding GrandChild to App's providers.

    However, I don't understand why you were annotating Child and GrandChild as @Component when you're using them as services. I guess this is what you actually wanted to do.

    @Injectable()
    export class GrandChild(){
      constructor () {
        this.hello = "hey!"
      }
    }
    
    @Injectable()
    export class Child {
        tire: string;
        constructor(public grandchild: GrandChild) {
            this.grandchild = grandchild;
        }
    }
    
    @Component({
        providers: [Child, GrandChild],
        template: `Everything rendered fine!`,
        selector: 'app'
    })
    export class App {
        thread: Thread;
        selected: boolean = false;
        kid: Child;
    
        constructor(public child: Child) {
            this.kid = child;
        }
    }
    

    See updated plnkr demo.

    0 讨论(0)
提交回复
热议问题