호스트 요소에“클래스”를 추가하는 방법은 무엇입니까?


190

<component></component>동적 클래스 속성을 구성 요소에 추가하는 방법을 모르지만 템플릿 html (component.html) 안에는 없습니다.

내가 찾은 유일한 해결책은 "ElementRef"기본 요소를 통해 항목을 수정하는 것입니다. 이 솔루션은 매우 간단한 작업을 수행하는 데 약간 복잡해 보입니다.

또 다른 문제는 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()method 를 수행해야했습니다 ngAfterViewInit(). 그렇지 않으면 작동하지 못했습니다.
John

실제 :host부품 작동 을 보여주는 포크를 여기에 만들었습니다 . 나는 @Component에서 호스트 매개 변수 () 장식 (구문이 나에게 명확하지 않다, 그리고에 대해 더 배울 수있는 곳 @Component 문서는 매우 설명하지 않습니다 ) (그것은 단지 나 원하는 HostBinding에 대해 자세히 알아 인터페이스로 나열 에 Angular2 사이트?)
The Red Pea

나는 더 나은 문서를 모른다. 그러나 그것은 당신이 할 수있는 일을하는 다른 방법 일 @Input() @Output() @HostBinding() @HostListener() @ViewChild(ren)() @ContentChild(ren)()
뿐이다

1
거꾸로 된 값을 반환하는 호스트 바인딩에 다른 이름의 게터를 사용하십시오@HostBinding('class.xxx') get xxxclass(){ return !this.someField;}
Günter Zöchbauer

1
@YochaiAkoka 당신이 무엇을 참조하는지 잘 모르겠습니다. 나는이 규칙을 모른다. 일반적으로 적은 것이 더 많으므로 추가 요소를 추가하지 않아도되는 경우 피해야합니다.
Günter Zöchbauer

184

Günter의 답변은 훌륭하지만 (질문은 동적 클래스 속성을 요구 합니다) 완전성을 위해 추가 할 것이라고 생각했습니다 ...

하나 이상의 정적 클래스를 구성 요소의 호스트 요소에 추가하는 (즉, 테마 스타일링 목적으로) 빠르고 깔끔한 방법을 찾고 있다면 다음을 수행 할 수 있습니다.

@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
The Red Pea

11
다른 방법은 변수를 건너 뛰는 것 @HostBinding('class.someClass') true;입니다. 구성 요소가 확장하는 모든 클래스 에서이 작업을 수행 할 수도 있습니다.
adamdport

3
여러 클래스를 추가하려면 호스트를 수행 할 수 있습니다 : { '[class]': ' "class1 class2"'}
jbojcic

4
host : {}변형 을 사용하는 경우 use-host-property-decorator설정을 false로 설정하십시오 tslint.json. 그렇지 않으면 IDE 경고가 표시됩니다. @adamdport 그 방법은 작동하지 않습니다 (더 이상). 앱에서 Angular 5.2.2 사용.
Ruud Voost

1
그것은 단지 나인가, 아니면 옛 방식은 새로운 방식보다 나을까? 나는 그들이 이주해야 할 충분한 이유가 있다고 확신하지만, meh ...
crush

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>요소의 템플릿에 추가하는 것이 아니라 태그의 요소입니다.
millimoose
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.