ホスト要素に「クラス」を追加するには?


190

コンポーネント<component></component>に動的クラス属性を追加する方法がわかりませんが、テンプレートhtml(component.html)内にあります。

私が見つけた唯一の解決策は、「ElementRef」ネイティブ要素を介してアイテムを変更することです。その解決策は、非常に単純なことを行うには少し複雑に見えます。

もう1つの問題は、CSSをコンポーネントのスコープ外で定義する必要があるため、コンポーネントのカプセル化が壊れることです。

より簡単な解決策はありますか?<root [class]="..."> .... </ root>テンプレート内のようなもの。

回答:


296
@Component({
   selector: 'body',
   template: 'app-element',
   // prefer decorators (see below)
   // host:     {'[class.someClass]':'someField'}
})
export class App implements OnInit {
  constructor(private cdRef:ChangeDetectorRef) {}

  someField: boolean = false;
  // alternatively also the host parameter in the @Component()` decorator can be used
  @HostBinding('class.someClass') someField: boolean = false;

  ngOnInit() {
    this.someField = true; // set class `someClass` on `<body>`
    //this.cdRef.detectChanges(); 
  }
}

プランカーの例

これにより、コンポーネントの外部にCSSを追加する必要がなくなります。CSSのような

:host(.someClass) {
  background-color: red;
}

コンポーネントの内部から機能し、セレクターは、クラスsomeClassがホスト要素に設定されている場合にのみ適用されます。


の代わりにsomeField = truein ngOnInit()メソッドを実行する必要がありましたngAfterViewInit()。それ以外の方法では機能しませんでした。
ジョン、

実際の:host部品が機能することを示すフォークをここに作成しました。@Component()デコレータのホストパラメータの詳細はどこで確認できますか(構文は私には明らかではなく、@ Componentのドキュメントではあまり説明されていません)または優先HostBindingの詳細を確認できます(インターフェイスとしてリストされているだけです) Angular2サイト?)
The Red Pea

私はより良いドキュメントを知りませんが、それはちょうどあなたが何ができるかやってのさまざまな方法だ@Input() @Output() @HostBinding() @HostListener() @ViewChild(ren)() @ContentChild(ren)()
ギュンターZöchbauer

1
その返します反転値を結合ホストに別の名前でゲッターを使う@HostBinding('class.xxx') get xxxclass(){ return !this.someField;}
ギュンターZöchbauer

1
@YochaiAkokaあなたが何を参照しているかわからない。私はこのルールを知りません。通常、少ない方が多いので、要素の追加を回避できる場合は、それを回避する必要があります。
ギュンターZöchbauer

184

ギュンターの答えは素晴らしいです(質問は動的クラス属性を求めています)が、完全を期すために追加すると思いました...

コンポーネントのホスト要素に1つ以上の静的クラスをすばやく簡単に追加する方法を探している場合(つまり、テーマスタイリングの目的で)、次のようにすることができます。

@Component({
   selector: 'my-component',
   template: 'app-element',
   host: {'class': 'someClass1'}
})
export class App implements OnInit {
...
}

そして、entryタグでクラスを使用すると、Angularはクラスをマージします。

<my-component class="someClass2">
  I have both someClass1 & someClass2 applied to me
</my-component>

1
シンプルにするためにこれが大好きです。ただし、私の場合、ホスト要素は別の属性でカプセル化されています。コンポーネントのngcontent_hostテンプレート, let's call those ngcontent_template , so if I put a style in the styleUrls` にある要素のどの属性よりも呼び出すと、ホスト要素には影響しませんngcontent_host。テンプレート要素にのみ影響を与えることができます。影響を与えることができるだけngcontent_templateです。私は間違っていますか?これについて何か提案はありますか?私は常に回すことができると思いますViewEncapsulation.None
赤エンドウ豆

11
もう1つの方法は、変数をスキップすることです@HostBinding('class.someClass') true;。コンポーネントが拡張する任意のクラスからこれを行うこともできます。
adamdport

3
ホストを使用して複数のクラスを追加するには、{'[class]': '"class1 class2"'}
jbojcic

4
host:{}バリアントを使用する場合、use-host-property-decorator設定をfalseinに設定することができますtslint.json。そうしないと、IDE警告が表示されます。@adamdportそのメソッドは(もう)機能しません。アプリでAngular 5.2.2を使用します。
ルードVoost

1
それは私だけですか、それとも古い方法が新しい方法よりも優れているように見えますか?私は確かに彼らが移行する正当な理由があったが、まあまあ...だ
クラッシュ

13

@Componentクラス@HostBinding('class') class = 'someClass';内に単純に追加できます。

例:

@Component({
   selector: 'body',
   template: 'app-element'       
})
export class App implements OnInit {

  @HostBinding('class') class = 'someClass';

  constructor() {}      

  ngOnInit() {}
}

1
クラス名のディレクティブを使用することもできるし、使用しないように優れているclass変数名(あなたはそれを参照して、それを後で変更する場合がありますので)として。例:@HostBinding('className') myTheme = 'theme-dark';
CPHPython


0

ここに私がそれをした方法があります(Angular 7):

コンポーネントに入力を追加します。

@Input() componentClass: string = '';

次に、コンポーネントのHTMLテンプレートに次のようなものを追加します。

<div [ngClass]="componentClass">...</div>

そして最後に、コンポーネントをインスタンス化するHTMLテンプレートで:

<root componentClass="someclass someotherclass">...</root>

免責事項:私はAngularにかなり慣れていないので、ここで幸運になるかもしれません!


2
わずかにネクロですが、これはCSSクラスをホスト要素に追加しません。これは<root>タグの要素であり、要素のテンプレートに追加するものではありません。
ミリムース
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.