template - property binding in angular 6




ربط HTML الزاوي (12)

أكتب تطبيق Angular ولدي استجابة HTML أريد عرضها.

كيف يمكنني فعل ذلك؟ إذا كنت ببساطة استخدم بناء جملة الربط {{myVal}} فهو يشفر جميع حروف HTML (بالطبع).

أحتاج بطريقة ما إلى ربط innerHTML الخاص بـ div بالقيمة المتغيرة.


أعتذر إذا كنت أفتقد هذه النقطة هنا ، لكنني أود أن أوصي بمقاربة مختلفة:

أعتقد أنه من الأفضل إعادة البيانات الأولية من تطبيق جانب الخادم الخاص بك وربطها بقالب من جانب العميل. هذا يجعل لطلبات أكثر ذكاء لأنك فقط تعود json من الخادم الخاص بك.

بالنسبة لي لا يبدو من المنطقي استخدام Angular إذا كان كل ما تفعله هو جلب html من الخادم وحقنه "كما هو" في DOM.

أعرف أن Angular 1.x لديه رابط html ، لكنني لم أر نظيرًا في Angular 2.0 حتى الآن. قد يضيفونه لاحقًا. على أي حال ، ما زلت أفكر في api للبيانات لتطبيق Angular 2.0.

لدي بعض العينات هنا مع بعض التجليد البسيط للبيانات إذا كنت مهتمًا: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples


إذا كان لديك قوالب في تطبيقك الزاوي (أو أي إطار عمل) ، وقمت بإرجاع قوالب HTML من الواجهة الخلفية الخاصة بك من خلال طلب / استجابة HTTP ، فأنت تمزج القوالب بين الواجهة الأمامية والخلفية.

لماذا لا تترك العناصر المغرية فقط في الواجهة الأمامية (أود أن أقترح ذلك) ، أو في الواجهة الخلفية (imo intransparent جميلة)؟

وإذا احتفظت بالقوالب في الواجهة الأمامية ، فلماذا لا تستجيب مع JSON فقط للطلبات إلى الواجهة الخلفية. ليس لديك حتى تطبيق بنية RESTful ، ولكن حفظ القوالب على جانب واحد يجعل الشفرة أكثر شفافية.

سيتم رد هذا المبلغ عندما يتعين على شخص آخر التعامل مع شفرتك (أو حتى أنت نفسك تعيد إدخال الرمز الخاص بك بعد فترة)!

إذا قمت بذلك بشكل صحيح ، فسيكون لديك مكونات صغيرة ذات قوالب صغيرة ، والأهم من ذلك كله ، إذا كانت الكود الخاص بك هو imba ، فسيتمكن شخص لا يعرف لغات الترميز من فهم قوالبك ومنطقك! بالإضافة إلى ذلك ، حافظ على وظائفك / طرقك صغيرة قدر الإمكان. سوف تكتشف في النهاية أن الحفاظ على الميزات وإعادة تنظيمها ومراجعتها وإضافتها سيكون أسهل كثيرًا مقارنة بالوظائف / الأساليب / الفئات الكبيرة وسيخلط بين الإغراء والمنطق بين الواجهة الأمامية والخلفية - ويحافظ على الكثير من المنطق في الواجهة الخلفية. إذا كانت الواجهة الأمامية الخاصة بك بحاجة إلى أن تكون أكثر مرونة (على سبيل المثال ، كتابة واجهة أمامية لنظام Android أو التبديل إلى إطار أمامي مختلف).

الفلسفة ، رجل :)

ملاحظة: ليس عليك تطبيق كود نظيف بنسبة 100٪ ، لأنه مكلف للغاية - خاصة إذا كان عليك تحفيز أعضاء الفريق ؛) ولكن: يجب أن تجد توازنًا جيدًا بين نهج الشفرة الأنظف وبين ما لديك (ربما يكون هو بالفعل نظيفة جدا)

تحقق من الكتاب إذا كنت تستطيع ودعه يدخل روحك: https://de.wikipedia.org/wiki/Clean_Code


إن استخدام [innerHTML] مباشرة دون استخدام المطهر DOM من Angular ليس خيارًا إذا كان يحتوي على محتوى أنشأه المستخدم. إن أنبوب safeHtml الذي اقترحه @ GünterZöchbauer في إجابته هو إحدى طرق تعقيم المحتوى. التوجيه التالي هو واحد آخر:

import { Directive, ElementRef, Input, OnChanges, Sanitizer, SecurityContext,
  SimpleChanges } from '@angular/core';

// Sets the element's innerHTML to a sanitized version of [safeHtml]
@Directive({ selector: '[safeHtml]' })
export class HtmlDirective implements OnChanges {
  @Input() safeHtml: string;

  constructor(private elementRef: ElementRef, private sanitizer: Sanitizer) {}

  ngOnChanges(changes: SimpleChanges): any {
    if ('safeHtml' in changes) {
      this.elementRef.nativeElement.innerHTML =
        this.sanitizer.sanitize(SecurityContext.HTML, this.safeHtml);
    }
  }
}

لاستخدامها

<div [safeHtml]="myVal"></div>

بناء الجملة الصحيح هو ما يلي:

<div [innerHTML]="theHtmlString"></div>

يعمل على 8.2.11

مرجع الوثائق


على [email protected]:

لن يعمل Html-Binding عند استخدام {{interpolation}} ، استخدم "تعبير" بدلاً من ذلك:

غير صالحة

<p [innerHTML]="{{item.anleser}}"></p>

-> يلقي خطأ (الاستيفاء بدلاً من التعبير المتوقع)

صيح

<p [innerHTML]="item.anleser"></p>

-> هذه هي الطريقة الصحيحة.

يمكنك إضافة عناصر إضافية إلى التعبير ، مثل:

<p [innerHTML]="'<b>'+item.anleser+'</b>'"></p>

ملحوظة

لم تتم معالجة HTML المضاف باستخدام [innerHTML] (أو تمت إضافته ديناميكيًا بوسائل أخرى مثل element.appenChild() أو ما شابه) بواسطة Angular بأي شكل من الأشكال باستثناء التعقيم من أجل الأمان المقصود.
تعمل مثل هذه الأشياء فقط عند إضافة HTML بشكل ثابت إلى قالب المكونات. إذا كنت بحاجة إلى ذلك ، يمكنك إنشاء مكون في وقت التشغيل كما هو موضح في كيف يمكنني استخدام / إنشاء قالب ديناميكي لتجميع مكون ديناميكي باستخدام Angular 2.0؟


فقط للحصول على إجابة كاملة ، إذا كان محتوى html في متغير مكون ، فيمكنك أيضًا استخدام:

<div [innerHTML]=componementVariableThatHasTheHtml></div>

ما عليك سوى استخدام السمة [innerHTML] في HTML ، مثل هذا أدناه:

<div [innerHTML]="myVal"></div>

هل سبق لك استخدام خصائص في مكونك تحتوي على بعض علامات HTML أو الكيانات التي تحتاج إلى عرضها في القالب الخاص بك؟ لن يعمل الاستيفاء التقليدي ، لكن ربط خاصية HTML الداخلي يندرج تحت الانقاذ.

استخدام {{myVal}} لا يعمل بالشكل المتوقع! لن يلتقط هذا علامات HTML مثل <p> و <strong> وما إلى ذلك ويمررها فقط على شكل سلاسل ...

تخيل أن لديك هذا الكود في مكونك:

const myVal:string ='<strong></strong> is <em>helpful!</em>'

إذا كنت تستخدم {{myVal}} ، {{myVal}} لك في العرض:

<strong></strong> is <em>helpful!</em>

ولكن استخدام [innerHTML]="myVal" يجعل النتيجة كما هو متوقع كما يلي:

مفيد!



يمكنك استخدام هذه الطريقة

<div [innerHTML]=var></div>

أو ربطه بواسطة معرف

 <div #html></div>

وفي المكون

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
    templateUrl: "some html file"
})
export class MainPageComponent {

    @ViewChild('dataContainer') dataContainer: ElementRef;

    loadData(data) {
        this.dataContainer.nativeElement.innerHTML = data;
    }
}

يمكنك تطبيق توجيهات متعددة للأسلوب والرابط و HTML كما يلي في .html

<div [innerHTML]="myVal"></div>

وفي الأنابيب .ts لمطهر "URL"

 import { Component, Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; @Pipe({ name: 'safeUrl' }) export class SafeUrlPipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(url) { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } } 

ماسورة المطهر "HTML"

 import { Component, Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; @Pipe({ name: 'safeHtml' }) export class SafeHtmlPipe implements PipeTransform { constructor(private sanitized: DomSanitizer) {} transform(value) { return this.sanitized.bypassSecurityTrustHtml(value); } } 

سيتم تطبيق هذا على حد سواء دون إزعاج أي نمط وحدث نقرة الارتباط


[innerHtml] خيارًا رائعًا في معظم الحالات ، لكنه يفشل مع سلاسل كبيرة جدًا أو عندما تحتاج إلى تصميم مرمّز بصيغة html.

أرغب في مشاركة طريقة أخرى:

كل ما عليك فعله هو إنشاء div في ملف html وإعطائه بعض المعرف:

<div #dataContainer></div>

ثم ، في مكون Angular 2 ، قم بإنشاء مرجع إلى هذا الكائن (TypeScript هنا):

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
    templateUrl: "some html file"
})
export class MainPageComponent {

    @ViewChild('dataContainer') dataContainer: ElementRef;

    loadData(data) {
        this.dataContainer.nativeElement.innerHTML = data;
    }
}

ثم ببساطة استخدام وظيفة loadData لإلحاق بعض النص إلى عنصر HTML.

إنها مجرد طريقة للقيام بذلك باستخدام جافا سكريبت أصلي ، ولكن في البيئة الزاوية. أنا لا أوصي به ، لأنه يجعل الشفرة أكثر فوضى ، لكن في بعض الأحيان لا يوجد خيار آخر.

انظر أيضًا .com/questions/36265026/…


الزاوي 2.0.0 و 4.0.0 الزاوي النهائي

للمحتوى الآمن فقط

<div [innerHTML]="myVal"></div>

DOMSanitizer

يجب أن يتم تمييز HTML غير الآمن المحتمل صراحة على أنه موثوق به باستخدام Angulars DOM sanitizer بحيث لا تجرد الأجزاء غير الآمنة من المحتوى

<div [innerHTML]="myVal | safeHtml"></div>

مع أنبوب مثل

@Pipe({name: 'safeHtml'})
export class Safe {
  constructor(private sanitizer:DomSanitizer){}

  transform(style) {
    return this.sanitizer.bypassSecurityTrustHtml(style);
    //return this.sanitizer.bypassSecurityTrustStyle(style);
    // return this.sanitizer.bypassSecurityTrustXxx(style); - see docs
  }
}

انظر أيضًا في RC.1 لا يمكن إضافة بعض الأنماط باستخدام بناء جملة الربط

والمستندات: https://angular.io/api/platform-browser/DomSanitizer

تحذير الأمان

ثقة المستخدم المضافة HTML قد يشكل خطرا على الأمن. حالة المستندات المذكورة أعلاه :

يؤدي استدعاء أيٍ من واجهات برمجة التطبيقات bypassSecurityTrust... تعطيل bypassSecurityTrust... Angular المضمن للقيمة التي تم تمريرها. تحقق بعناية من جميع القيم ومسارات التعليمات البرمجية التي تدخل هذه المكالمة bypassSecurityTrust... . تأكد من أن بيانات المستخدم قد تم تجاوزها بشكل مناسب لسياق الأمان هذا. لمزيد من التفاصيل ، انظر دليل الأمن .

العلامات الزاوية

شيء مثل

class FooComponent {
  bar = 'bar';
  foo = `<div>{{bar}}</div>
    <my-comp></my-comp>
    <input [(ngModel)]="bar">`;

مع

<div [innerHTML]="foo"></div>

لن يتسبب Angular في معالجة أي شيء خاص بـ Angular في foo . الزاوي يستبدل العلامات الزاوي محددة في وقت البناء مع رمز ولدت. لن تتم معالجة العلامات المضافة في وقت التشغيل بواسطة Angular .

لإضافة HTML الذي يحتوي على علامات الزاوي المحددة (خاصية أو ربط القيمة ، والمكونات ، والتوجيهات ، والأنابيب ، ...) مطلوب لإضافة الوحدة النمطية الديناميكية وتجميع المكونات في وقت التشغيل. توفر هذه الإجابة مزيدًا من التفاصيل. كيف يمكنني استخدام / إنشاء قالب ديناميكي لتجميع المكونات الديناميكية باستخدام Angular 2.0؟







angular2-databinding