angular-ngSanitize模組-linky過濾器詳解

詩&遠方發表於2014-11-19

本篇主要講解angular中的linky這個過濾器.此過濾器依賴於ngSanitize模組.

linky能找出文字中的連結,然後把它轉換成html連結.什麼意思,就是說,一段文字里有一個連結,但是這個連結沒有被a標籤巢狀,linky能把它找出來,然後給它加上a標籤並且給a連結新增正確的href屬性,還可以設定開啟的方式(_blank,_self,等...).

它查詢連結是根據這些關鍵詞來的: http/https/ftp/mailto/,或者就直接是一個email地址.

下面來看栗子:

html:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <title></title>
  <meta charset="utf-8">
  <script src="../angular-1.3.2.js"></script>
  <script src="angular-sanitize.min.js"></script>
  <script src="script.js"></script>
  <link type="text/css" href="../bootstrap.css" rel="stylesheet" />
</head>
<body>
<div class="container">
  <table class="table table-bordered" ng-controller="ctrlLinky">
    <caption>通過ngSanitize模組的linky過濾器編譯連結</caption>
    <thead>
    <tr>
      <th>過濾方式</th>
      <th>指令的寫法</th>
      <th>解析結果</th>
    </tr>
    </thead>
    <tbody>
    <tr>
      <td>使用linky編譯連結</td>
      <td><pre>&lt;div ng-bind-html="myHtml | linky"&gt;<br>&lt;/div&gt;</pre></td>
      <td><div ng-bind-html="myHtml | linky"></div></td>
    </tr>
    <tr>
      <td>使用linky+target編譯連結</td>
      <td><pre>&lt;div ng-bind-html="myHtml | linky:'_blank'"&gt;<br>&lt;/div&gt;</pre></td>
      <td><div ng-bind-html="myHtml | linky:'_blank'"></div></td>
    </tr>
    <tr>
      <td>不編譯連結</td>
      <td><pre>&lt;div ng-bind-html="myHtml"&gt;<br>&lt;/div&gt;</pre></td>
      <td><div ng-bind-html="myHtml"></div></td>
    </tr>
    </tbody>
  </table>
  <a class="btn btn-default" href="http://plnkr.co/edit/I9j13MnyuDwOJPnBiKE1?p=preview" role="button">plunker</a>
</div>
</body>
</html>

js:

var app =angular.module('myApp',['ngSanitize']);

app.controller('ctrlLinky',function($scope,$sce){
    $scope.myHtml = '<p>'+
    '下面這些都應該是連結:\n'+
    'http://angularjs.org/,\n'+
    'mailto:us@somewhere.org,\n'+
    'another@somewhere.org,\n'+
    'and one more: ftp://127.0.0.1/.\n'+
    '</p>';
});

結果:

點選檢視效果: http://plnkr.co/edit/I9j13MnyuDwOJPnBiKE1?p=preview 

下面來具體說明一下這個栗子:

表格第一行:

myHtml是一段html,使用ng-bind-html來繫結(關於這個,詳見angular-ngSanitize模組-$sanitize服務詳解),然後使用linky過濾器,使myHtml裡的連結都轉換為可點選的a連結.

*注意,一旦使用了linky過濾器,則$sanitize淨化不能生效,ng-bind-html也不能被解析為元素的html,僅能對連結部分進行轉換.所以這裡的p標籤還是出現在了內容裡.而不是作為html的p標籤.

表格第二行:

給linky新增引數: '_blank',表示連結在新視窗中開啟.其餘同上.

表格第三行:

不使用linky過濾器,所以$sanitize服務會淨化myHtml,然後作為.html()繫結到div裡.所以可以看到,p標籤是成為標籤了,而不是文字內容的一部分.

 

另外,注入$filter服務後可以這樣用:

$filter('linky')(htmlString,target)

可以得到htmlString經過linky過濾器編譯的結果.

eg:

app.controller('ctrlLinky',function($scope,$sce,$filter){
    $scope.myHtml = '<p>'+
    '下面這些都應該是連結:\n'+
    'http://angularjs.org/,\n'+
    'mailto:us@somewhere.org,\n'+
    'another@somewhere.org,\n'+
    'and one more: ftp://127.0.0.1/.\n'+
    '</p>';
    console.log($filter('linky')($scope.myHtml,'_blank'))
});

結果:

&lt;p&gt;&#19979;&#38754;&#36825;&#20123;&#37117;&#24212;&#35813;&#26159;&#38142;&#25509;:&#10;<a target="_blank" href="http://angularjs.org/">http://angularjs.org/</a>,&#10;<a target="_blank" href="mailto:us@somewhere.org">us@somewhere.org</a>,&#10;<a target="_blank" href="mailto:another@somewhere.org">another@somewhere.org</a>,&#10;and one more: <a target="_blank" href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.&#10;&lt;/p&gt; 

 

相關閱讀: angular-ngSanitize模組-$sanitize服務詳解

參考原文: https://docs.angularjs.org/api/ngSanitize/filter/linky

完整程式碼: https://github.com/OOP-Code-Bunny/angular/tree/master/ngSanitize

相關文章