Ana bilgisayar öğesine “sınıf” nasıl eklenir?


191

Nasıl bileşenimi <component></component>dinamik sınıf özniteliği eklemek için bilmiyorum ama şablon html (component.html) içinde.

Bulduğum tek çözüm, öğeyi "ElementRef" yerel öğesi aracılığıyla değiştirmektir. Bu çözüm, çok basit bir şey yapmak için biraz karmaşık görünüyor.

Başka bir sorun ise, CSS'nin bileşen kapsama alanını kırarak bileşen kapsamı dışında tanımlanması gerektiğidir.

Daha basit bir çözüm var mı? <root [class]="..."> .... </ root>Şablonun içindeki gibi bir şey .

Yanıtlar:


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

Plunker örneği

Bu şekilde CSS'yi bileşenin dışına eklemenize gerek yoktur. CSS benzeri

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

bileşenin içinden çalışır ve seçici yalnızca sınıf someClassana öğe üzerinde ayarlanmışsa uygulanır .


Bunun yerine someField = truein- ngOnInit()metodu yapmak zorunda kaldım ngAfterViewInit(). Aksi halde çalıştıramadım.
John

Burada gerçek :hostparçanın çalıştığını gösteren bir çatal yaptım . Ben @Component konak parametresi () dekoratör (sözdizimi bana bariz değildir ve hakkında daha fazla bilgi nerelerde @Component dokümantasyon çok açıklamaz ) (yalnızca oluyor veya tercih HostBinding hakkında daha fazla bilgi bir arayüzü olarak listelenmiş üzerinde Angular2 sitesi?)
Kızıl Bezelye

Daha iyi dokümanlar bilmiyorum, ama yapabileceğinizi yapmanın farklı bir yolu@Input() @Output() @HostBinding() @HostListener() @ViewChild(ren)() @ContentChild(ren)()
Günter Zöchbauer

1
tersine çevrilmiş değeri döndüren ana bilgisayar bağlaması için farklı bir ada sahip bir alıcı kullanın@HostBinding('class.xxx') get xxxclass(){ return !this.someField;}
Günter Zöchbauer

1
@YochaiAkoka ne kastettiğinizden emin değil. Bu kuralın farkında değilim. Daha azı genellikle daha fazladır, bu nedenle ek öğeler eklemekten kaçınabilirseniz, bundan kaçınmalısınız.
Günter Zöchbauer

185

Günter'in cevabı harika (soru dinamik sınıf özelliği istiyor ) ama sadece bütünlük için ekleyeceğimi düşündüm ...

Bileşeninizin ana bilgisayar öğesine bir veya daha fazla statik sınıf eklemenin hızlı ve temiz bir yolunu arıyorsanız (yani, tema şekillendirme amaçları için) şunları yapabilirsiniz:

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

Giriş etiketinde bir sınıf kullanırsanız, Angular sınıfları birleştirir, yani,

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

1
Bunu basitlik için seviyorum. Ancak benim durumumda, host öğesi farklı bir öznitelikle kapsüllenmişse, onu bileşenimin ngcontent_template styleUrls` ngcontent_hostşablonumdaki , let's call those öğelerdeki özniteliklerden herhangi birinden daha , so if I put a style in the çağıralım, etkilemeyecekleri için ana bilgisayar öğesini etkilemezler ngcontent_host, yalnızca şablon öğelerini etkileyebilir; sadece etkileyebilirler ngcontent_template. Yanlış mıyım? Bu konuda herhangi bir öneriniz var mı? Sanırım her zaman dönebilirimViewEncapsulation.None
The Red Pea

11
Başka bir yol da değişkeni atlamaktır @HostBinding('class.someClass') true;. Hatta bunu, bileşeninizin genişlettiği herhangi bir sınıftan da yapabilirsiniz.
adamdport

3
Birden fazla sınıf eklemek için host yapabilirsiniz: {'[class]': '"class1 class2"'}
jbojcic

4
Host: {}varyantını kullanıyorsanız, use-host-property-decoratorayarı falsein olarak ayarlamak isteyebilirsiniz tslint.json. Aksi takdirde IDE uyarıları alırsınız. @adamdport Bu yöntem artık çalışmıyor. Bizim app Açısal 5.2.2 kullanma.
Ruud Voost

1
Sadece ben mi, yoksa eski yol yeni yoldan daha mı iyi görünüyor? Eminim göç etmek için iyi bir nedenleri vardı, ama meh ...
ezmek

14

@Component sınıfınızın @HostBinding('class') class = 'someClass';içine kolayca ekleyebilirsiniz .

Misal:

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

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

  constructor() {}      

  ngOnInit() {}
}

1
ClassName yönergesi de kullanılabilir ve kullanmaktan kaçınmak için daha iyidir classdeğişken adı olarak (bunu referans olabileceğinden ve daha sonra değiştirebilir). Örnek: @HostBinding('className') myTheme = 'theme-dark';.
CPHPython

4

Ana makine öğenize dinamik bir sınıf eklemek istiyorsanız, HostBindingöğenizi bir alıcıyla birleştirebilirsiniz.

@HostBinding('class') get class() {
    return aComponentVariable
}

Https://stackblitz.com/edit/angular-dynamic-hostbinding adresinde Stackblitz demosu


0

İşte böyle yaptım (Açısal 7):

Bileşene bir giriş ekleyin:

@Input() componentClass: string = '';

Sonra bileşenin HTML şablonuna şöyle bir şey ekleyin:

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

Ve son olarak bileşeni örneklediğiniz HTML şablonunda:

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

Feragatname: Angular için oldukça yeniyim, bu yüzden burada şanslı olabilirim!


2
Biraz necro ama: Bu, ana öğe öğesine CSS sınıfını eklemez - <root>etiketin öğesi olan öğenin şablonuna eklediğiniz hiçbir şey değildir.
millimoose
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.