AngularJS動(dòng)態(tài)綁定HTML的方法分析
本文實(shí)例講述了AngularJS動(dòng)態(tài)綁定HTML的方法。分享給大家供大家參考,具體如下:
在Web前端開發(fā)中,我們經(jīng)常會(huì)遇見(jiàn)需要?jiǎng)討B(tài)的將一些來(lái)自后端或者是動(dòng)態(tài)拼接的HTML字符串綁定到頁(yè)面DOM顯示,特別是在內(nèi)容管理系統(tǒng)(CMS:是Content Management System的縮寫),這樣的需求,更是遍地皆是。
對(duì)于對(duì)angular的讀者肯定首先會(huì)想到ngBindHtml,對(duì),angular為我們提供了這個(gè)指令來(lái)動(dòng)態(tài)綁定HTML,它會(huì)將計(jì)算出來(lái)的表達(dá)式結(jié)果用innerHTML綁定到DOM。但是,問(wèn)題并不是這么簡(jiǎn)單。在Web安全中XSS(Cross-site scripting,腳本注入攻擊),它是在Web應(yīng)用程序中很典型的計(jì)算機(jī)安全漏洞。XSS攻擊指的是通過(guò)對(duì)網(wǎng)頁(yè)注入可執(zhí)行客戶端代碼且成功地被瀏覽器執(zhí)行,來(lái)達(dá)到攻擊的目的,形成了一次有效XSS攻擊,一旦攻擊成功,它可能會(huì)獲取到用戶的一些敏感信息、改變用戶的體驗(yàn)、誘導(dǎo)用戶等非法行為,有時(shí)XSS攻擊還會(huì)合其他攻擊方式同時(shí)實(shí)施比如SQL注入攻擊服務(wù)器和數(shù)據(jù)庫(kù)、Click劫持、相對(duì)鏈接劫持等實(shí)施釣魚,它帶來(lái)的危害是巨大的,也是web安全的頭號(hào)大敵。更多的Web安全問(wèn)題,請(qǐng)參考wiki https://en.wikipedia.org/wiki/Cross-site_scripting%E3%80%82
在angular中默認(rèn)是不相信添加的HTML內(nèi)容,對(duì)于添加的HTML內(nèi)容,首先必須利用$sce.trustAsHtml,告訴angular這是可信的HTML內(nèi)容。否則你將會(huì)得到$sce:unsafe的異常錯(cuò)誤。
Error: [$sce:unsafe] Attempting to use an unsafe value in a safe context.
下面是一個(gè)綁定簡(jiǎn)單的angular鏈接的demo:
HTML:
<div ng-controller="DemoCtrl as demo"> <div ng-bind-html="demo.html"></div> </div>
JavaScript:
angular.module("com.ngbook.demo", [])
.controller("DemoCtrl", ["$sce", function($sce) {
var vm = this;
var html = '<p>hello <a ;
vm.html = $sce.trustAsHtml(html);
return vm;
}]);
對(duì)于簡(jiǎn)單的靜態(tài)HTML,這個(gè)問(wèn)題就解決了。但對(duì)于復(fù)雜的HTML,這里的復(fù)雜是指帶有angular表達(dá)式、指令的HTML模板,對(duì)于它們來(lái)說(shuō),我們不僅希望綁定大DOM顯示,同時(shí)還希望得到angular強(qiáng)大的雙向綁定機(jī)制。ngBindHhtml并不會(huì)和$scope關(guān)聯(lián)雙向綁定,如果在HTML中存在ngClick、ngHref、ngSHow、ngHide等angular指令,它們并不會(huì)被compile,點(diǎn)擊這些按鈕,也不會(huì)發(fā)生任何反應(yīng),綁定的表達(dá)式也不會(huì)在更新。例如嘗試將上次的鏈接變?yōu)椋簄g-href=“demo.link”,鏈接并不會(huì)被解析,在DOM看見(jiàn)的仍然會(huì)是原樣的HTML字符串。
在angular中的所有指令要生效,都需要經(jīng)過(guò)compile,在compile中包含了pre-link和post-link,連接上特定行為,才能工作。大部分情況下compile,是會(huì)在angular啟動(dòng)時(shí),自動(dòng)compile的。但如果是對(duì)于動(dòng)態(tài)添加的模板,則需要手動(dòng)的compile。angular中為我們提供了$compile服務(wù)來(lái)實(shí)現(xiàn)這一功能。下面是一個(gè)比較通用的compile例子:
HTML:
<body ng-controller="DemoCtrl as demo">
<dy-compile html="{{demo.html}}">
</dy-compile>
<button ng-click="demo.change();">change</button>
</body>
JavaScript:
angular.module("com.ngbook.demo", [])
.directive("dyCompile", ["$compile", function($compile) {
return {
replace: true,
restrict: 'EA',
link: function(scope, elm, iAttrs) {
var DUMMY_SCOPE = {
$destroy: angular.noop
},
root = elm,
childScope,
destroyChildScope = function() {
(childScope || DUMMY_SCOPE).$destroy();
};
iAttrs.$observe("html", function(html) {
if (html) {
destroyChildScope();
childScope = scope.$new(false);
var content = $compile(html)(childScope);
root.replaceWith(content);
root = content;
}
scope.$on("$destroy", destroyChildScope);
});
}
};
}])
.controller("DemoCtrl", [function() {
var vm = this;
vm.html = '<h2>hello : <a ng-href="{{demo.link}}">angular</a></h2>';
vm.link = 'https://angular.io/';
var i = 0;
vm.change = function() {
vm.html = '<h3>change after : <a ng-href="{{demo.link}}">' + (++i) + '</a></h3>';
};
}]);
這里創(chuàng)建了一個(gè)叫dy-compile的指令,它首先會(huì)監(jiān)聽(tīng)綁定屬性html值的變化,當(dāng)html內(nèi)容存在的時(shí)候,它會(huì)嘗試首先創(chuàng)個(gè)一個(gè)子scope,然后利用$compile服務(wù)來(lái)動(dòng)態(tài)連接傳入的html,并替換掉當(dāng)前DOM節(jié)點(diǎn);這里創(chuàng)建子scope的原因,是方便在每次銷毀DOM的時(shí),也能容易的銷毀掉scope,去掉HTML compile帶來(lái)的watchers函數(shù),并在最后的父scope銷毀的時(shí)候,也會(huì)嘗試銷毀該scope。
因?yàn)橛辛松线叺腸ompile的編譯和連接,則ngHref指令就可以生效了。這里只是嘗試給出動(dòng)態(tài)compile angular模塊的例子,具體的實(shí)現(xiàn)方式,請(qǐng)參照你的業(yè)務(wù)來(lái)聲明特定的directive。
希望本文所述對(duì)大家AngularJS程序設(shè)計(jì)有所幫助。
相關(guān)文章
詳解AngularJS1.x學(xué)習(xí)directive 中‘& ’‘=’ ‘@’符號(hào)的區(qū)別使用
這篇文章主要介紹了詳解AngularJS1.x學(xué)習(xí)directive 中‘& ’‘=’ ‘@’符號(hào)的區(qū)別使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-08-08
Angular.js中window.onload(),$(document).ready()的寫法淺析
這篇文章主要介紹了Angular.js中window.onload(),$(document).ready()的寫法淺析,需要的朋友可以參考下2017-09-09
在Angular項(xiàng)目使用socket.io實(shí)現(xiàn)通信的方法
這篇文章主要介紹了在Angular項(xiàng)目使用socket.io實(shí)現(xiàn)通信的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
AngularJS基礎(chǔ) ng-mouseover 指令簡(jiǎn)單示例
本文主要介紹AngularJS ng-mouseover 指令,這里幫大家整理了AngularJS 指令的基礎(chǔ)知識(shí),并附代碼示例,有興趣的小伙伴可以參考下2016-08-08
Angular CLI在Angular項(xiàng)目中如何使用scss詳解
angular-cli自身支持Scss預(yù)處理器,Scss比css更加方便靈活,而且層次清晰,代碼整潔。下面這篇文章主要給大家介紹了關(guān)于Angular CLI在Angular項(xiàng)目中如何使用scss的相關(guān)資料,需要的朋友可以參考下。2018-04-04
angular4 獲取wifi列表中文顯示亂碼問(wèn)題的解決
這篇文章主要介紹了angular4 獲取wifi列表中文顯示亂碼問(wèn)題的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
AngularJS ionic手勢(shì)事件的使用總結(jié)
本篇文章主要介紹了AngularJS手勢(shì)事件的使用總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08

