Saya menulis aplikasi Angular dan saya memiliki respons HTML yang ingin saya tampilkan.
Bagaimana aku melakukan itu? Jika saya hanya menggunakan sintaks yang mengikat {{myVal}}
itu mengkodekan semua karakter HTML (tentu saja).
Saya perlu entah bagaimana untuk mengikat innerHTML
dari div
nilai variabel.
Jawaban:
Sintaks yang benar adalah sebagai berikut:
Referensi Dokumentasi
sumber
Final Angular 2.0.0 dan Angular 4.0.0
Untuk konten yang aman saja
DOMSanitizer
Potensi HTML yang tidak aman perlu secara eksplisit ditandai sebagai tepercaya menggunakan Angulars DOM sanitizer sehingga tidak menghapus bagian yang berpotensi tidak aman dari konten
dengan pipa seperti
Lihat juga Di RC.1 beberapa gaya tidak dapat ditambahkan menggunakan sintaks yang mengikat
Dan dokumen: https://angular.io/api/platform-browser/DomSanitizer
Peringatan keamanan
Pengguna percaya menambahkan HTML dapat menimbulkan risiko keamanan. Status dokumen yang disebutkan sebelumnya :
Markup sudut
Sesuatu seperti
dengan
tidak akan menyebabkan Angular memproses apa pun yang khusus untuk Angular
foo
. Angular menggantikan markup spesifik sudut pada waktu pembuatan dengan kode yang dihasilkan. Markup yang ditambahkan saat runtime tidak akan diproses oleh Angular .Untuk menambahkan HTML yang berisi markup spesifik sudut (pengikatan properti atau nilai, komponen, arahan, pipa, ...) diperlukan untuk menambahkan modul dinamis dan mengkompilasi komponen saat runtime. Jawaban ini memberikan detail lebih lanjut. Bagaimana cara menggunakan / membuat template dinamis untuk mengkompilasi Komponen dinamis dengan Angular 2.0?
sumber
import { BrowserModule, DomSanitizer } from '@angular/platform-browser'
import { Pipe } from '@angular/core'
[innerHtml]
adalah pilihan yang bagus dalam banyak kasus, tetapi gagal dengan string yang sangat besar atau ketika Anda membutuhkan gaya hard-coded di html.Saya ingin berbagi pendekatan lain:
Yang perlu Anda lakukan adalah membuat div di file html Anda dan berikan beberapa id:
Kemudian, di komponen Angular 2 Anda, buat referensi ke objek ini (Ketik Script di sini):
Kemudian cukup gunakan
loadData
fungsi untuk menambahkan beberapa teks ke elemen html.Ini hanya cara yang akan Anda lakukan menggunakan javascript asli, tetapi dalam lingkungan Angular. Saya tidak merekomendasikannya, karena membuat kode lebih berantakan, tetapi terkadang tidak ada pilihan lain.
Lihat juga Angular 2 - gaya dalamHTML
sumber
nativeElement
secara langsung yang dianggap praktik buruk. Saya yakin[innerHTML]="..."
melakukan hal yang sama di bawah tenda tetapi dengan cara latihan Angular2 yang baik.[innerHTML]
dan string besar di Angular2?[innerHtml]
menghapus gaya hard-coded di Html. Untuk mengintegrasikan editor wysiwyg, saya harus menggunakan pendekatan yang tercantum di sini.[innerHTML]
pendekatannya tidak.Pada [email protected]:
Binding-Html tidak akan berfungsi saat menggunakan
{{interpolation}}
, gunakan "Ekspresi" sebagai gantinya:tidak valid
-> melempar kesalahan (Interpolasi alih-alih Ekspresi yang diharapkan)
benar
-> ini adalah cara yang benar.
Anda dapat menambahkan elemen tambahan ke ekspresi, seperti:
petunjuk
HTML yang ditambahkan menggunakan
[innerHTML]
(atau ditambahkan secara dinamis dengan cara lain yangelement.appenChild()
serupa atau serupa) tidak akan diproses oleh Angular dengan cara apa pun kecuali sanitasi untuk tujuan keamanan.Hal-hal seperti itu hanya berfungsi ketika HTML ditambahkan secara statis ke templat komponen. Jika Anda memerlukan ini, Anda dapat membuat komponen saat runtime seperti dijelaskan di Bagaimana saya bisa menggunakan / membuat template dinamis untuk mengkompilasi Komponen dinamis dengan Angular 2.0?
sumber
Menggunakan [innerHTML] secara langsung tanpa menggunakan pembersih DOM Angular bukanlah suatu opsi jika mengandung konten yang dibuat pengguna. Pipa safeHtml yang disarankan oleh @ GünterZöchbauer dalam jawabannya adalah salah satu cara untuk membersihkan konten. Arahan berikut adalah satu lagi:
Untuk digunakan
sumber
Can't bind to 'safeHtml' since it isn't a known property of 'div'.
ng-versi 2.4.4constructor( private sanitizer: Sanitizer) {}
dan mengikat hasilnya menjadi apa pun yang Anda butuhkan, juga penggunaan ElementRef sangat tidak disarankan.Ini bekerja untuk saya:
<div innerHTML = "{{ myVal }}"></div>
(Angular2, Alpha 33)Menurut SO lain: Memasukkan HTML dari server ke DOM dengan angular2 (manipulasi DOM umum di Angular2) , "inner-html" setara dengan "ng-bind-html" di Angular 1.X
sumber
Hanya untuk membuat jawaban yang lengkap, jika konten html Anda ada dalam variabel komponen, Anda juga bisa menggunakan:
sumber
Saya minta maaf jika saya kehilangan poin di sini, tetapi saya ingin merekomendasikan pendekatan yang berbeda:
Saya pikir lebih baik mengembalikan data mentah dari aplikasi sisi server Anda dan mengikatnya ke templat di sisi klien. Ini membuat permintaan lebih gesit karena Anda hanya mengembalikan json dari server Anda.
Bagi saya sepertinya tidak masuk akal untuk menggunakan Angular jika semua yang Anda lakukan adalah mengambil html dari server dan menyuntikkannya "sebagaimana adanya" ke DOM.
Saya tahu Angular 1.x memiliki html mengikat, tetapi saya belum melihat rekan di Angular 2.0. Mereka mungkin menambahkannya nanti. Bagaimanapun, saya masih akan mempertimbangkan data api untuk aplikasi Angular 2.0 Anda.
Saya punya beberapa sampel di sini dengan beberapa data sederhana yang mengikat jika Anda tertarik: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples
sumber
Jawaban singkat sudah disediakan di sini: gunakan
<div [innerHTML]="yourHtml">
penjilidan.Namun saran lain yang disebutkan di sini mungkin menyesatkan. Angular memiliki mekanisme sanitasi bawaan ketika Anda mengikat properti seperti itu. Karena Angular bukan perpustakaan sanitasi yang berdedikasi, itu terlalu bersemangat untuk konten yang mencurigakan untuk tidak mengambil risiko. Misalnya, itu membersihkan semua konten SVG menjadi string kosong.
Anda mungkin mendengar saran untuk "membersihkan" konten Anda dengan menggunakan
DomSanitizer
untuk menandai konten sebagai aman denganbypassSecurityTrustXXX
metode. Ada juga saran untuk menggunakan pipa untuk melakukan itu dan pipa itu sering disebutsafeHtml
.Semua ini menyesatkan karena sebenarnya memotong sanitasi , bukan membersihkan konten Anda. Ini bisa menjadi masalah keamanan karena jika Anda melakukan ini pada konten yang disediakan pengguna atau pada apa pun yang Anda tidak yakin - Anda membuka diri untuk serangan kode berbahaya.
Jika Angular menghapus sesuatu yang Anda butuhkan dengan sanitasi bawaan - yang dapat Anda lakukan alih-alih menonaktifkannya adalah mendelegasikan sanitasi aktual ke perpustakaan khusus yang ahli dalam tugas itu. Misalnya - DOMPurify.
Saya telah membuat perpustakaan pembungkus untuk itu sehingga dapat dengan mudah digunakan dengan Angular: https://github.com/TinkoffCreditSystems/ng-dompurify
Ini juga memiliki pipa untuk membersihkan HTML secara deklaratif:
Perbedaan dengan pipa yang disarankan di sini adalah bahwa itu benar-benar melakukan sanitasi melalui DOMPurify dan karenanya bekerja untuk SVG.
Satu hal yang perlu diingat adalah DOMPurify sangat bagus untuk membersihkan HTML / SVG, tetapi tidak untuk CSS. Jadi, Anda dapat menyediakan pembersih CSS Angular untuk menangani CSS:
Ini adalah
ɵ
awalan internal-padat , tetapi ini adalah cara tim Angular menggunakannya di paket mereka sendiri juga. Perpustakaan itu juga berfungsi untuk Angular Universal dan lingkungan sisi server renedring.sumber
Cukup gunakan
[innerHTML]
atribut dalam HTML Anda , sesuatu seperti ini di bawah ini:Menggunakan
{{myVal}}
TIDAK berfungsi seperti yang diharapkan! Ini tidak akan mengambil tag HTML seperti<p>
,<strong>
dll dan meneruskannya hanya sebagai string ...Bayangkan Anda memiliki kode ini di komponen Anda:
const myVal:string ='<strong>Stackoverflow</strong> is <em>helpful!</em>'
Jika Anda menggunakan
{{myVal}}
, Anda akan mendapatkan ini dalam tampilan:tetapi menggunakan
[innerHTML]="myVal"
membuat hasil seperti yang diharapkan seperti ini:Stackoverflow sangat membantu!
sumber
Anda dapat menerapkan beberapa pipa untuk gaya, tautan, dan HTML sebagai berikut di .html
dan dalam pipa .ts untuk pembersih 'URL'
pipa untuk pembersih 'HTML'
ini akan berlaku baik tanpa mengganggu gaya apa pun dan tautan acara klik
sumber
The innerHtml adalah properti dari HTML-Elements, yang memungkinkan Anda untuk mengatur itu html-konten programatik. Ada juga properti innerText yang mendefinisikan konten sebagai teks biasa.
Itu
[attributeName]="value"
kotak braket, sekitar atribut mendefinisikan sudut input-mengikat. Itu berarti, bahwa nilai properti (dalam kasus Anda innerHtml) terikat dengan ekspresi yang diberikan, ketika hasil ekspresi berubah, nilai properti juga berubah.Jadi pada dasarnya
[innerHtml]
memungkinkan Anda untuk mengikat dan secara dinamis mengubah html-conent dari HTML-Element yang diberikan.sumber
Di Angular 2 Anda dapat melakukan 3 jenis binding:
[property]="expression"
-> Setiap properti html dapat ditautkan keekspresi. Dalam kasus ini, jika ekspresi perubahan properti akan memperbarui, tetapi ini tidak bekerja sebaliknya.
(event)="expression"
-> Ketika acara diaktifkan, jalankan ekspresi.[(ngModel)]="property"
-> Mengikat properti dari js (atau ts) ke html. Setiap pembaruan pada properti ini akan terlihat di mana-mana.Ekspresi dapat berupa nilai, atribut, atau metode. Misalnya: '4', 'controller.var', 'getValue ()'
Contoh di sini
sumber
Cara menambahkan elemen secara dinamis ke DOM, seperti yang dijelaskan pada Angular 2 doc, adalah dengan menggunakan kelas ViewContainerRef dari @ Angular / core.
Yang harus Anda lakukan adalah mendeklarasikan arahan yang akan mengimplementasikan ViewContainerRef dan bertindak seperti placeholder di DOM Anda.
Pengarahan
Lalu, di templat tempat Anda ingin menyuntikkan komponen:
HTML
Kemudian, dari kode komponen yang disuntikkan, Anda akan menyuntikkan komponen yang berisi HTML yang Anda inginkan:
Saya menambahkan aplikasi demo yang berfungsi penuh pada Angular 2 secara dinamis menambahkan komponen ke demo DOM
sumber
Anda dapat menggunakan beberapa pendekatan untuk mencapai solusi. Seperti yang sudah dikatakan dalam jawaban yang disetujui, Anda dapat menggunakan:
tergantung pada apa yang ingin Anda capai, Anda juga dapat mencoba hal-hal lain seperti javascript DOM (tidak disarankan, operasi DOM lambat):
Presentasi
Komponen
Binding Properti
Javascript DOM Outer HTML
sumber
getElementsById
atau metode pemilihan lainnya buruk karena mungkin menangkap elemen yang dimiliki komponen yang sama sekali berbeda jika mengandung elemen dengan id yang sama (atau kriteria lain).Kami selalu dapat meneruskan konten html ke
innerHTML
properti untuk merender konten dinamis html tetapi konten html dinamis itu juga dapat terinfeksi atau berbahaya. Jadi sebelum meneruskan konten dinamis keinnerHTML
kita harus selalu memastikan konten tersebut disanitasi (menggunakanDOMSanitizer
) sehingga kita dapat lolos dari semua konten berbahaya.Coba di bawah pipa:
sumber
style: background-color
semua hal bisa dihapus dan jadi sebaiknya mulai menggunakan ini dari awal atau Anda akan menjadi sangat bingung nanti.Jika Anda menginginkannya dalam Angular 2 atau Angular 4 dan juga ingin menyimpan inline CSS maka Anda dapat menggunakannya
sumber
Anda juga dapat mengikat properti kelas komponen sudut dengan templat menggunakan bentuk kanonik seperti di bawah ini:
Dokumentasi Sudut: https://angular.io/guide/template-syntax#property-binding-property
Lihat contoh stackblitz yang berfungsi di sini
sumber
Bekerja di Angular v2.1.1
sumber
<div _ngcontent-luf-0=""></div>
untuk saya. Itudiv
kosong.Jika Anda memiliki template di aplikasi sudut (atau kerangka kerja apa pun) Anda, dan Anda mengembalikan template HTML dari backend Anda melalui permintaan / respons HTTP, Anda sedang mencampur template antara frontend dan backend.
Mengapa tidak meninggalkan barang-barang templating baik di frontend (saya akan menyarankan itu), atau di backend (imo cukup transparan)?
Dan jika Anda menyimpan templat di frontend, mengapa tidak merespons dengan JSON untuk permintaan ke backend. Anda bahkan tidak harus mengimplementasikan struktur RESTful, tetapi menjaga templat di satu sisi membuat kode Anda lebih transparan.
Ini akan membayar kembali ketika orang lain harus mengatasi kode Anda (atau bahkan Anda sendiri memasukkan kembali kode Anda sendiri setelah beberapa saat)!
Jika Anda melakukannya dengan benar, Anda akan memiliki komponen kecil dengan templat kecil, dan yang paling penting, jika kode Anda imba, seseorang yang tidak tahu bahasa pengkodean akan dapat memahami templat dan logika Anda! Jadi tambahan, jaga fungsi / metode Anda sekecil mungkin. Anda pada akhirnya akan mengetahui bahwa memelihara, refactoring, meninjau, dan menambahkan fitur akan jauh lebih mudah dibandingkan dengan fungsi / metode / kelas besar dan mencampuradukkan templating dan logika antara frontend dan backend - dan menjaga sebanyak mungkin logika di backend jika frontend Anda harus lebih fleksibel (misalnya menulis frontend android atau beralih ke kerangka frontend yang berbeda).
Filsafat, teman :)
ps: Anda tidak harus menerapkan kode bersih 100%, karena sangat mahal - terutama jika Anda harus memotivasi anggota tim;) tetapi: Anda harus menemukan keseimbangan yang baik antara pendekatan kode bersih dan apa yang Anda miliki (mungkin itu sudah cukup bersih)
periksa buku jika Anda bisa dan biarkan masuk ke jiwa Anda: https://de.wikipedia.org/wiki/Clean_Code
sumber