Góc 2 - kiểu bên trongHTML


170

Tôi nhận được các đoạn mã HTML từ các cuộc gọi HTTP. Tôi đặt các khối HTML vào một biến và chèn nó vào trang của mình bằng [InternalHTML] nhưng tôi không thể định kiểu khối HTML được chèn. Có ai có bất cứ đề nghị làm thế nào tôi có thể đạt được điều này?

@Component({selector: 'calendar',
template: '<div [innerHTML]="calendar"></div>',
providers:[HomeService], 
styles: [` 
h3 {color:red;}
`})

HTML mà tôi muốn tạo kiểu là khối chứa trong biến "lịch".


Phong cách từ đâu? Từ trong thành phần hoặc từ phong cách thêm vào index.html?
Günter Zöchbauer 28/03/2016

ý bạn là can not style the inserted HTML blockgì Chỉ cho chúng tôi những gì đã làm cho nó với đoạn mã nhỏ.
micronyks 28/03/2016

Ive cập nhật bài viết của tôi với một đoạn mã! :) cảm ơn
Jakob Svenningsson

1
Tôi đã thêm một liên kết Plunker vào câu trả lời của mình
Günter Zöchbauer 28/03/2016

@ GünterZöchbauer nếu mã HTML có css nội tuyến thì sao? nó sẽ được kết xuất như thế nào?
iniravpatel

Câu trả lời:


320

cập nhật 2 ::slotted

::slotted hiện được hỗ trợ bởi tất cả các trình duyệt mới và có thể được sử dụng với ViewEncapsulation.ShadowDom

https://developer.mozilla.org/en-US/docs/Web/CSS/::sliated

cập nhật 1 :: ng-sâu

/deep/đã bị phản đối và thay thế bởi ::ng-deep.

::ng-deep cũng đã được đánh dấu không dùng nữa, nhưng vẫn chưa có sự thay thế nào.

Khi ViewEncapsulation.Nativeđược hỗ trợ chính xác bởi tất cả các trình duyệt và hỗ trợ tạo kiểu theo ranh giới DOM bóng, ::ng-deepcó thể sẽ bị ngừng.

nguyên

Angular thêm tất cả các loại lớp CSS vào HTML, nó thêm vào DOM để mô phỏng đóng gói CSS DOM bóng tối để ngăn chặn các kiểu chảy máu vào và ra khỏi các thành phần. Angular cũng viết lại CSS mà bạn thêm để khớp với các lớp được thêm này. Đối với HTML được thêm bằng [innerHTML]các lớp này không được thêm vào và CSS được viết lại không khớp.

Như một cách giải quyết

  • cho CSS được thêm vào thành phần
/* :host /deep/ mySelector { */
:host ::ng-deep mySelector { 
  background-color: blue;
}
  • cho CSS được thêm vào index.html
/* body /deep/ mySelector { */
body ::ng-deep mySelector {
  background-color: green;
}

>>>(và tương đương /deep/nhưng /deep/hoạt động tốt hơn với SASS) và ::shadowđã được thêm vào 2.0.0-beta.10. Chúng tương tự như các tổ hợp CSS DOM bóng tối (không dùng nữa) và chỉ hoạt động với encapsulation: ViewEncapsulation.Emulatedmặc định trong Angular2. Họ có thể cũng làm việc với ViewEncapsulation.Nonenhưng sau đó chỉ bị bỏ qua vì không cần thiết. Các tổ hợp này chỉ là một giải pháp trung gian cho đến khi các tính năng nâng cao hơn cho kiểu dáng thành phần chéo được hỗ trợ.

Một cách tiếp cận khác là sử dụng

@Component({
  ...
  encapsulation: ViewEncapsulation.None,
})

cho tất cả các thành phần chặn CSS của bạn (tùy thuộc vào nơi bạn thêm CSS và nơi HTML bạn muốn tạo kiểu - có thể là tất cả các thành phần trong ứng dụng của bạn)

Cập nhật

Ví dụ Plunker


6
Chỉ cần một lưu ý cho bất kỳ ai, điều này không hoạt động với nút-sass hoặc với styleUrl. Chỉ trong các phong cách: [...]
thouliha

12
Với SASS sử dụng /deep/thay vì>>>
Günter Zöchbauer 8/12/2016

1
Bạn không thể có các chỉ thị hoặc thành phần trong nội dung được thêm vàoinneeHTML
Günter Zöchbauer

1
Nếu HTML được cung cấp bởi cuộc gọi HTTP là lớn và nó có css nội tuyến thì điều đó sẽ khả thi như thế nào vì tôi không có các kiểu được xác định trước, tôi chỉ nhận được nó từ css nội tuyến @ GünterZöchbauer
iniravpatel 10/03/2017

1
Đã lưu ngày trong Angular 8! Thanx. Thật khó để có được câu hỏi đúng để tìm câu trả lời này!
Pianoman

12

Giải pháp đơn giản bạn cần tuân theo là

import { DomSanitizer } from '@angular/platform-browser';

constructor(private sanitizer: DomSanitizer){}

transformYourHtml(htmlTextWithStyle) {
    return this.sanitizer.bypassSecurityTrustHtml(htmlTextWithStyle);
}

2

Nếu bạn đang cố gắng định kiểu động các phần tử HTML được thêm vào bên trong một thành phần Angular, điều này có thể hữu ích:

// inside component class...

constructor(private hostRef: ElementRef) { }

getContentAttr(): string {
  const attrs = this.hostRef.nativeElement.attributes
  for (let i = 0, l = attrs.length; i < l; i++) {
    if (attrs[i].name.startsWith('_nghost-c')) {
      return `_ngcontent-c${attrs[i].name.substring(9)}`
    }
  }
}

ngAfterViewInit() {
  // dynamically add HTML element
  dynamicallyAddedHtmlElement.setAttribute(this.getContentAttr(), '')
}

Tôi đoán là quy ước cho thuộc tính này không được đảm bảo ổn định giữa các phiên bản của Angular, do đó người ta có thể gặp vấn đề với giải pháp này khi nâng cấp lên phiên bản mới của Angular (mặc dù, việc cập nhật giải pháp này có thể là tầm thường trong đó trường hợp).


2

Chúng tôi thường xuyên lấy nội dung từ CMS của mình [innerHTML]="content.title". Chúng tôi đặt các lớp cần thiết trong styles.scsstệp gốc của ứng dụng thay vì trong tệp scss của thành phần. CMS của chúng tôi cố tình loại bỏ các kiểu nội tuyến để chúng tôi phải chuẩn bị các lớp mà tác giả có thể sử dụng trong nội dung của họ. Hãy nhớ sử dụng {{content.title}}trong mẫu sẽ không hiển thị html từ nội dung.


-3

Nếu bạn đang sử dụng sass làm bộ tiền xử lý kiểu, bạn có thể chuyển về trình biên dịch Sass gốc cho phụ thuộc dev bằng cách:

npm install node-sass --save-dev

Vì vậy, bạn có thể tiếp tục sử dụng / sâu / để phát triển.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.