繁体   English   中英

Angular2异常:没有服务提供者

[英]Angular2 Exception: No provider for Service

当我拥有嵌套在根组件下的组件时,我无法实例化我的应用程序,该组件providing了在其构造函数中使用的组件。

import {Component, Injectable} from 'angular2/core';


@Component()
export class GrandChild(){
  constructor () {
    this.hello = "hey!"
  }
}

@Component({
  providers: [GrandChild]
})
@Injectable()
export class Child {
    constructor(public grandchild: GrandChild) {
        this.grandchild = grandchild;
    }
}

@Component({
    providers: [Child],
    template: `Everything rendered fine!`,
    selector: 'app'
})

export class App {
    kid: Child;

    constructor(public child: Child) {
        this.kid = child;
    }
}

EXCEPTION: No provider for GrandChild! (App -> Child -> GrandChild)

我想知道为什么这种行为是非法的。 假设我想在Child类中使用GrandChild类,而在App类中仅引用Child类。 这似乎是不可能的。

创建provide层次结构的正确方法是什么?

谢谢你

PLNKR: http ://plnkr.co/edit/5Z0QMAEyZNUAotZ6r7Yi?p=preview

您可以直接将父组件注入到组件中,而无需将其指定到组件提供程序中。 为此,您需要在其他组件中使用组件并将其设置为directives属性:

@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() {
  }
}

您的示例中有些奇怪的是,您没有为组件ChildGrandChild定义selectortemplate属性。 它们真的是组成部分吗?

在您的示例中,您以错误的方式进行操作。 如果要从父组件获取子组件的实例,则需要利用@ViewChild装饰器通过注入从父组件引用子组件:

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();
  }
}

这是更新的plunkr: http ://plnkr.co/edit/mrVK2j3hJQ04n8vlXLXt?p=preview。

您会注意到,也可以使用@Query参数修饰符:

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

  (...)
}

您可能会注意到,拥有@Component一个时就不需要@Injectable装饰器了。

您可以通过将GrandChild添加到App的提供App来修复它。

但是,我不明白为什么在将它们用作服务时为什么将ChildGrandChild标注为@Component 我想这就是您真正想要做的。

@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;
    }
}

请参阅更新的plnkr演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM