Angular2 异常:没有服务提供者 [英] Angular2 Exception: No provider for Service

查看:31
本文介绍了Angular2 异常:没有服务提供者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我有一个嵌套在根组件下的组件 providing 一个它在其构造函数中使用的组件时,我无法实例化我的应用程序.

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 constructor.

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 类班级.这似乎是不可能的.

I'm wondering why this behavior is illegal. Let's say I wanted to use the GrandChild class in my Child class and simply reference the Child class in my App class. This seems to be impossible.

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

What is the correct way to create the provide hierarchy?

非常感谢.

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

推荐答案

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

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

您的示例中有点奇怪的是您没有为组件 Child 定义 selectortemplate 属性孙子.它们真的是组件吗?

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?

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

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

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

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

您可以注意到也可以使用 @Query 参数装饰器:

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

  (...)
}

您会注意到,当您拥有 @Component 装饰器时,您不需要 @Injectable 装饰器...

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

这篇关于Angular2 异常:没有服务提供者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆