簡體   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