Angular を使用して動的読み込みコンポーネントメソッドを使用してダイアログを実装する方法

php中世界最好的语言
リリース: 2018-05-30 11:32:00
オリジナル
1805 人が閲覧しました

今回は、Angular を使用して動的ローディング コンポーネント メソッドを使用して Dialog を実装する方法を説明します。 、見てみましょう。 インターネット上の記事やチュートリアルは、基本的にコンポーネントが読み込まれると終了します。消えた? !また、ダイアログは 1 つしか存在できません。別のダイアログを開きたい場合は、まず現在開いているダイアログを破棄する必要があります。資料の実装を見た後、ソース コードを理解するには愚かであると自分を責めるので、実装することしかできません。 Dialog コンポーネントが利用可能になりました

Dialog コンポーネントの目的: 複数の Dialog が同時に存在でき、指定された Dialog は破棄された後に HTML に残りません。コンポーネントを動的にロードするには 2 つの方法があり、angular4.0 バージョンの ComponentFactoryResolver が実装されるまでは、より便利な ngComponentOutlet を使用して実装できます。 ComponentFactoryResolver

まず、ViewChild、ViewChildren、ElementRef、ViewContainerRef、ViewRef、ComponentRef、ComponentFactoryResolver の関係を整理しましょう:

ViewChild と ViewChildrenViewChild は Angular Dom

抽象クラス

を取得するために使用されますテンプレートを通して参照

変数

(#) またはディレクティブ (ディレクティブ) は、ElementRef または ViewContainerRef を使用してカプセル化できます。

@ViewChild('customerRef') customerRef:ElementRef;
ログイン後にコピー
ViewChildren は、複数の ViewChild で構成される配列などのテンプレート参照変数または命令を通じて QueryList を取得するために使用されます。

@ViewChildren(ChildDirective) viewChildren: QueryList<ChildDirective>;
ログイン後にコピー

ElementRef と ViewContainerRefViewChild は、ElementRef または ViewContainerRef を使用してカプセル化できます。では、ElementRef と ViewContainerRef の違いは何でしょうか。

ElementRef を使用してカプセル化してから、.nativeElement を使用してネイティブ Dom 要素を取得します

console.log(this.customerRef.nativeElement.outerHTML);
ログイン後にコピー

ViewContainerRef: ビューのコンテナー (ビューの作成方法とビューを操作するための API (コンポーネントとテンプレートを一緒に含む) を含む)ビューを定義します)。 API は ComponentRef と ViewRef を返しますが、これら 2 つは何でしょうか?

// 使用ViewContainetRef时,请使用read声明
@ViewChild('customerRef',{read: ViewContainerRef}) customerRef:ViewContainerRef;
···
this.customerRef.createComponent(componentFactory) // componentFactory之后会提到
ログイン後にコピー

ViewRef と ComponentRef

ViewRef は、ViewContainerRef API が動作し、ViewRef を取得します。ホスト ビュー (コンポーネント インスタンス ビュー) は、ViewContainerRef を通じてコン​​ポーネント ビューへの参照を作成し、コンポーネントのビューを取得できます。情報を取得してコンポーネントのメソッドを呼び出します

ComponentFactoryResolver

ComponentRef を取得するには、ViewContainer の createComponent メソッドを呼び出す必要があります。このメソッドは、ComponentFactoryResolver

constructor(
 private componentFactoryResolver:ComponentFactoryResolver
) { }
viewInit(){
  componentFactory = 
   this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
  // 获取对组件视图的引用,到这一步就已经完成了组件的动态加载
  componentRef = this.customerRef.createComponent(componentFactory);
  // 调用载入的组件的方法
  componentRef.instance.dialogInit(component);
}
ログイン後にコピー

特定の実装によって作成されたパラメーターを渡す必要があります。

letComponentFactory、componentRef;

@ViewChild('customerRef',{read: ViewContainerRef}) customerRef:ViewContainerRef;
constructor(
 private componentFactoryResolver:ComponentFactoryResolver
) { }
viewInit(){
 // DialogComponent:你想要动态载入的组件,customerRef:动态组件存放的容器
  componentFactory = 
   this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
  componentRef = this.customerRef.createComponent(componentFactory);
}
ログイン後にコピー

ngComponentOutletを通じて動的ロードを実現

ngComponentOutletはコード量を大幅に削減しますが、4.0以降のバージョンでのみサポートされます

詳細な実装

Dialog.component.html の storage ノード

<ng-container *ngComponentOutlet="componentName"></ng-container>
ログイン後にコピー
コンポーネント (コンポーネント名ではなく) を渡すだけでOKです。なぜこんなに簡単なのでしょうか。
dialogInit(component){
  this.componentName = component;
};
ログイン後にコピー

ダイアログの実装

実装のアイデアは次のとおりです。まず、他のコンポーネントをホストするダイアログ コンポーネントを作成し、ダイアログのマスクとアニメーションを作成し、ダイアログの生成と破棄を制御するサービスを確立します。ただし、サービスはダイアログを生成するだけです。ダイアログ内のコンポーネントは引き続きダイアログ コンポーネントで生成する必要があります。 1. まず、ルート コンポーネントの viewContainerRef を取得するパブリック サービスを作成します (ルートの viewContainerRef を取得するために ApplicationRef を試しました)。コンポーネントを作成しましたが失敗したので、サービスとして書きました)

gerRootNode(...rootNodeViewContainerRef){
  if(rootNode){
   return rootNode;
  }else {
   rootNode = rootNodeViewContainerRef[0];
  };
}
// 然后再根组件.ts内调用
this.fn.gerRootNode(this.viewcontainerRef);
ログイン後にコピー

2.dialog.service.tsを作成し、openとcloseの3つのメソッドを定義し、ViewContainerRefを使用してダイアログコンポーネントを作成します。作成する前に、ComponentFactoryResloverを呼び出して渡す必要があります。 DialogComponent は

let componentFactory;
let componentRef;
@Injectable()
export class DialogService {
 constructor(
    private componentFactoryResolver:ComponentFactoryResolver
    private fn:FnService
  ) { }   
 open(component){
  componentFactory = 
   this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
  
  // 这里的获取的是ComponentRef
  containerRef = this.fn.gerRootNode().createComponent(componentFactory); 
  
  // 将containerRef存储下来,以便之后的销毁
  containerRefArray.push(containerRef);
  
  // 调用了组件内的初始化方法,后面会提到
  return containerRef.instance.dialogInit(component,containerRef);
 }
  // 这里有两种情况,一种是在当前组件和dialog组件关闭调用的,因为有返回值所以可以关闭指定的dialog;还有一种是在插入到dialog组件内的组件调用的,因为不知道父组件的信息,所以默认关闭最后一个dialog
 close(_containerRef=null){
  if( _containerRef ){
   return _containerRef.containerRef.instance.dialogDestory();
  }else{
   containerRefArray.splice(-1,1)[0].instance.dialogDestory();
  }
 }
}
ログイン後にコピー

3.dialog.component.ts にあります。ここでは ngComponentOutlet を使用して実装します (ngComponentOutlet については後述しますが、面倒なので直接使用します)

let containerRef,dialogRef = new DialogRef();
export class DialogComponent implements OnInit {
 componentName;
 constructor(
  private fn:FnService
 ) { }
 dialogInit( _component, _containerRef){
  this.componentName = _component;
  containerRef = _containerRef;
  dialogRef['containerRef'] = containerRef;
  return dialogRef;
 };
 dialogDestory(){
  let rootNode = this.fn.gerRootNode();
  // 等待动画结束再移除
  setTimeout(()=>{
  // 这里用到了 viewContainerRef 里的indexOf 和 remove 方法
   rootNode.remove(rootNode.indexOf(containerRef.hostView));
  },400);
  dialogRef.close();
  return true;
 };
 
}
ログイン後にコピー

4、这里还创建了一个 DialogRef 的类,用来处理 dialog 关闭后的回调,这样就可以使用 XX.afterClose().subscribe() 来创建回调的方法了

@Injectable()
export class DialogRef{
 public afterClose$ = new Subject();
 constructor(){}
 close(){
  this.afterClose$.next();
  this.afterClose$.complete();
 }
 afterClose(){
  return this.afterClose$.asObservable();
 }
}
ログイン後にコピー

创建和销毁dialog

// 创建
let _viewRef = this.dialogService.open(DialogTestComponent);
_viewRef.afterClose().subscribe(()=>{
  console.log('hi');
});
// 销毁
this.dialogService.close()
ログイン後にコピー

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样操作Node.js 使用jade模板引擎

Node.js Express安装与使用详细介绍

以上がAngular を使用して動的読み込みコンポーネントメソッドを使用してダイアログを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート