ホームページ > 記事 > ウェブフロントエンド > ViewProviders と Angular のプロバイダーの違い
今回は、Angular での ViewProviders と Providers の違いについて説明します。 Angular で ViewProviders と Providers を使用する際の 注意事項 について、実際のケースを見てみましょう。
Angular でDependency Injection (DI) を使用する場合、通常は providers
を使用します。実際、同じことを行うための別のオプション、viewProviders
があります。 providers
。其实要做同样的事我们还有另外一个选择:viewProviders
。
viewProviders
允许我们定义只对组件的view可见的provider。下面我们用例子详细的说明这一点。
假设我们有一个简单的服务:
// myService.service.ts import { Injectable } from '@angular/core'; @Injectable() export class MyService{ testIfGetService(where){ console.log('Got My Service in ' + where); } }
这个服务很简单,只需要打印出在哪里调用了该服务。
然后有一个子组件,是用来投射到父组件里面的(等会将会看到):
// child.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-child', template: ` <p>This is child!!!</p> ` }) export class VPChild{ constructor( private service: MyService ){ this.service.testIfGetService('child'); } }
这个组件注入了MyService
服务,调用MyService
的testIfGetService
方法,并传入child
表明这是在child组件调用的。
还有另外一个子组件,这个组件是用来放在父组件的模板(template)里面的:
// viewChild.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-viewchild', template: ` <p>This is viewChild!!!</p> ` }) export class ViewVPChild{ constructor( private service: MyService ){ this.service.testIfGetService('viewChild'); } }
这里同样注入MyService
服务,调用MyService
服务的testIfGetService
方法,并传入viewChild
。
最后是父组件:
// parent.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-parent', template: ` <p>This is parent!!!</p> <ng-content></ng-content> <vp-viewchild></vp-viewchild> `, providers: [MyService] }) export class VPParent{ constructor( private service: MyService ){ this.service.testIfGetService('parent'); } }
在父组件,用providers
注册MyService
,然后调用MyService
的testIfGetService
传入parent
。
然后就像这样使用父组件:
<vp-parent> <vp-child></vp-child> </vp-parent>
运行程序,控制台打印出了结果:
一切就像预期那样!!
然后,我们用viewProviders
代替providers
注册MyService
,看看会发生什么:
// parent.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-parent', template: ` <p>This is parent!!!</p> <ng-content></ng-content> <vp-viewchild></vp-viewchild> `, viewProviders: [MyService] // <--- }) export class VPParent{ constructor( private service: MyService ){ this.service.testIfGetService('parent'); } }
这样修改之后,运行程序,发现报错了:
如果把contentChild注释掉,就像这样:
<vp-parent> <!-- <vp-child></vp-child> --> </vp-parent>
是不会报错的:
这就说明,在父组件用viewProviders
注册的provider,对contentChildren是不可见的。而使用providers
注册的provider,对viewChildren和contentChildren都可见!
补充说明:组件会逐级向上寻找provider,直到找到为止,否则就会抛出错误。就像这里:
<vp-parent> <vp-child></vp-child> </vp-parent>
vp-child
往上找MyService
的provider,结果在vp-parent
找到了。但是在用viewProviders
的时候,vp-child
往上找,也就是到vp-parent
,结果没找到,然后又去找vp-parent
的父级,还是没找到(因为在这个例子里,我们只在vp-parent
注册了MyService
),然后又继续往上找……如此找到边界也没找到,所以抛出了一个错误。如果你不希望这样,可以使用@Host
viewProviders
を使用すると、コンポーネントのビューにのみ表示されるプロバイダーを定義できます。以下では、例を使用してこの点を詳しく説明します。
constructor( @Host() private service: MyService ){}このサービスは非常に単純で、サービスが呼び出される場所を出力するだけです。
次に、親コンポーネントに投影するために使用される子コンポーネントがあります (後で説明します):
rrreeeこのコンポーネントは、MyService
サービスを挿入し、MyService
を呼び出します。 >testIfGetService
メソッドを使用し、child
を渡すことは、これが子コンポーネントで呼び出されることを示します。
rrreeeMyService
サービスもここに挿入され、MyService
はService の testIfGetService
メソッドを呼び出し、viewChild
に渡します。 最後に、親コンポーネント:
rrreee
MyService
を providers
に登録し、MyService の <code>testIfGetService
を呼び出します。 >parent
を渡します。 次に、次のように親コンポーネントを使用します: rrreeeプログラムを実行すると、コンソールに結果が出力されます:
providers
の代わりに viewProviders
を使用して MyService
を登録し、何が起こるかを確認します。 🎜rrreee🎜 この変更後、プログラムを実行して、エラーが発生しました: 🎜🎜🎜 contentChild次のように 🎜 をコメントアウトします: 🎜rrreee🎜 はエラーを報告しません: 🎜🎜🎜これは、親コンポーネントの viewProviders
で登録されたプロバイダーが contentChildren には表示されないことを意味します。 providers
を使用して登録されたプロバイダーは、viewChildren と contentChildren の両方に表示されます。 🎜追加説明: コンポーネントはプロバイダーを段階的に検索し、見つからない場合はエラーがスローされます。以下のように: 🎜rrreee🎜vp-child
は MyService
のプロバイダーを探し、vp-parent
でそれを見つけました。しかし、viewProviders
を使用すると、vp-child
は上方向、つまり vp-parent
まで検索され、結果は見つかりません。 vp-parent
の親はまだ見つかりません (この例では vp-parent
のみを登録しているため)。 code>) と入力し、上方向に検索を続けました...境界は見つけましたが、見つからず、エラーがスローされました。これを望まない場合は、次のように @Host
を使用して制限を加えることができます: 🎜rrreee🎜この記事は @Host() については展開しません。興味がある場合は、Google で調べてください。あなた自身。 🎜🎜この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。 🎜🎜推奨読書: 🎜🎜🎜Vue.js フォーム入力バインディング🎜🎜🎜🎜🎜 React にはどのようなクラス定義コンポーネントがあるか🎜🎜🎜以上がViewProviders と Angular のプロバイダーの違いの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。