web-dev-qa-db-ja.com

コンポーネントを使用してダイナミックHTMLをDIVにロードする方法は? Angular5

私はこの問題の解決策を2日から見つけようとしてきました。残念ながら、私は欲しいものを手に入れることができません。私はAngular5を使用しています。

<div class="form-group col-md-12" [innerHTML]="GetItemsOfHolder(item.children[1],1,
'UserConfigGroupsLabelHolder') | keepHtml"></div>

これは私の関数のようです:

GetItemsOfHolder(item: any,divName:string, recursive: boolean = false,typeName:string="") 
{
return html;
}

私が返すHTMLに Select2 という名前のパッケージが含まれていない限り、すべてが正常に機能しますこのdivには非常にうまく機能します。動的パッケージを追加するまで。

つまり、return htmlには次のようなパッケージコンポーネントが含まれています。

itemhtml +="<select2 data-type='"+holderItem.itemType+"' 
[data]='this.dropdownData."+holderItem.name+"'></select2>"  

これはブラウザにプレーンテキストを返すだけで、期待どおりに機能しません。

私が欲しいのは、文字列をコンポーネントに変換するか、select2ドロップダウンを機能させ生成する他の方法です。

私は非常に多くのものを検索しようとしましたが、それは機能しません これは良いですが、これを理解できません そしてdynamiccomponentloadingは非推奨です。

誰でも私にアイデアを教えてもらえますか?この問題をどのように解決できますか?どんな例でも素晴らしいでしょう。

16
Just code

@Devconのコメント通り

Angularはほとんどすべてをサニタイズするため、プレーンテキストを取得しています。調べたいのはReflectiveInjectorであり、主にComponentFactoryResolverです。主なアイデアは、コンポーネントがレンダリングされる他の情報(サービス、他のコンポーネントなど)を必要とすることです。したがって、Injectorを使用してDependency Injection refを取得し、コンポーネントファクトリがコンポーネントをビルドします。次に、これをViewChild参照に挿入します。コンパイラを使用し、ModuleWithComponentFactoriesを必要とするコンポーネントを動的に作成するより複雑な方法があります。これはangularが実際に使用するものです。

そして、角度で検索すると、angularをこのようにすべきではないことを受け入れます。

HTMLでレンダリングする必要がある完全に動的なページを作成する必要があるため。 jsonを少し変更し、 ng-containerng-templatengswitch を使用して、自分でテンプレートで再帰呼び出しを行い、動作していることがわかりました非常に細かい。

これを使用すると多くの利点が得られます。HTML(動的にレンダリング)自体はHTMLであり、コードはクリーンで読みやすく、簡単に入手できます。

ここに示した例は、私がやったこととほとんど同じです。 https://stackoverflow.com/a/40530244/2630817

小さな例を次に示します。

<ng-template #itemsList let-itemsList>
  <div *ngFor="let item of itemsList;let i = index">
    <div [ngSwitch]="item.itemType">
        <div class="form-group" *ngSwitchCase="'TEXT'">
            <label>
                {{item.label}}
              </label>
              <input id="{{item.name}}" value="{{item.value}}" type='text' class='form-control txtbox ui-autocomplete-input'/>
        </div>
        <div class="form-group" *ngSwitchCase="'PASSWORD'">
            <label>
                {{item.label}}
              </label>
              <input id="{{item.name}}" value="{{item.value}}" type='password' class='form-control txtbox ui-autocomplete-input'/>
        </div>
        <div class="form-group" *ngSwitchCase="'BOOLEAN'">
            <label style='width:40%'>{{item.label}}</label>
            <div class="form-group"><input id="{{item.name}}" type='checkbox' /></div>

        </div>
        <div  class="form-group" *ngSwitchCase="'LABEL'">
            <label class="form-control">{{item.label}}</label>
        </div>
        <div class="form-group"  *ngSwitchDefault>
            <label>
                {{item.label}}
              </label>
              <select2 class="form-control"  [data]="GetDropDowndata(item.holderId)" [cssImport]="false" [width]="300" [options]="GetOptions(item.type)"></select2>
          </div>
    </div>
  </div>
8
Just code

必要なものをすべて1つのdivに読み込むことができます。ng-templateとng-contentで遊んでください。

まず、1つのディレクティブを作成する必要があります。

import {Directive, ViewContainerRef} from '@angular/core';

@Directive({
  selector: '[dynamic]',
  exportAs: 'dynamicdirective'
})
export class DynamicDirective {

  constructor(public viewContainerRef: ViewContainerRef) { }

}

次のようなng-templateに配置する必要があります。

<p>
  page works!
</p>


<ng-template #sider=dynamicdirective dynamic></ng-template>

そしてそれを次のように使用します

import {Component, ComponentFactoryResolver, OnInit, ViewChild} from '@angular/core';


@Component({
  selector: 'app-page',
  templateUrl: './page.component.html',
  styleUrls: ['./page.component.css']
})
export class PageComponent implements OnInit {

  @ViewChild('sider')
  sider;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {
  }

  ngOnInit() {
    
      const componentFactory = this.componentFactoryResolver.resolveComponentFactory(SomeComponent);
 this.sider.viewContainerRef.createComponent(componentFactory);
    });
   
  }

}

通常、ng-templateの場所にコンポーネントが読み込まれます(ビューをリセットする場合は、 https://angular.io/api/core/ViewContainerRef#clear を呼び出すことができます)

私はすでにこれで遊んでいます、あなたはここでいくつかのコードを見つけることができます https://github.com/nicearma/dynamic

3
nicearma