2016-01-28 47 views
1

我從來沒有見過這樣做的API,但我正在處理我所擁有的。這是我處理如何將數組中的字符串與Angular創建HTML標記?

"body": { 
    "isRichText":true, 
    "messageSegments":[ 
    { 
     "htmlTag":"p", 
     "markupType":"Paragraph", 
     "text":"", 
     "type":"MarkupBegin" 
    }, 
    { 
     "text":"This is a ", 
     "type":"Text" 
    }, 
    { 
     "htmlTag":"b", 
     "markupType":"Bold", 
     "text":"", 
     "type":"MarkupBegin" 
    }, 
    { 
     "text":"post", 
     "type":"Text" 
    }, 
    { 
     "htmlTag":"b" 
     ,"markupType":"Bold", 
     "text":"", 
     "type":"MarkupEnd" 
    }, 
    { 
     "text":" from the standard ", 
     "type":"Text" 
    }, 
    { 
     "htmlTag":"i", 
     "markupType":"Italic", 
     "text":"", 
     "type":"MarkupBegin" 
    }, 
    { 
     "text":"chatter", 
     "type":"Text" 
    }, 
    { 
     "htmlTag":"i", 
     "markupType":"Italic", 
     "text":"", 
     "type":"MarkupEnd" 
    }, 
    { 
     "text":" UI with some HTML tags", 
     "type":"Text" 
    }, 
    { 
     "htmlTag":"p", 
     "markupType":"Paragraph", 
     "text":"\n", 
     "type":"MarkupEnd" 
    } 
    ] 
} 

我需要這些段的每一個結合,以創造什麼,都會變成一個段落標記中一個元素的API響應身體的一部分(在此案件)。

HTML

<div ng-repeat="bodyElement in post.body.messageSegments"> 
    <!-- ng-if maybe? -->{{bodyElement.htmlTag}} {{bodyElement.text}} 
</div> 

什麼是完成這一目標的最佳方式是什麼?它直接在js文件中,還是應該在模板中嘗試?

+0

所有html都需要在視圖之外手動創建。 API顯然是通過模板腳本運行的。如果你無法找到用於解析html的庫,那麼將會做很多工作。它是公開的API與參考文檔? – charlietfl

+0

@charlietfl你喜歡跟我來到你身邊:)謝謝。文檔是公開的,但是你將無法達到終點。這是Salesforce Chatter API https://developer.salesforce.com/docs/atlas.en-us.198.0.chatterapi.meta/chatterapi/connect_responses_feed_item_body.htm – TheEks

+0

必須假定他們有SDK來將其解析爲html。我自己從頭開始做這樣的事情,如果你必須覆蓋所有的標籤,這是一大堆工作......特別是如果你將包括表單標籤...並需要一段時間來獲得表單控件整理和測試 – charlietfl

回答

1

我的建議是創建一個服務來解析消息段,以及一個指令來顯示結果。

這裏是一個工作示例:JSFiddle

服務

服務$messageSegment有兩個方法:parseparseHttpResponse。後者可用於$http請求的transformResponse配置選項。

angular.module('myApp') 
    .factory('$messageSegment', messageSegmentFactory); 

function messageSegmentFactory() { 
    var $messageSegment = {}; 

    $messageSegment.parse = function(arr) { 
    var html = ''; 

    if (!angular.isArray(arr) || !arr.length) 
     return html; 

    do { 
     var segment = arr.shift(); 
     switch (segment.type) { 
     case 'Link': 
      html += '<a href="' + segment.url + '">' + segment.text + '</a>'; 
      break; 
     case 'Mention': 
      html += '<a href="https://stackoverflow.com/users/' + segment.user.id + '">' + segment.text + '</a>'; 
      break; 
     case 'Hashtag': 
      html += '<a class="hashtag">' + segment.text + '</a>'; 
      break; 
     case 'MarkupBegin': 
      html += '<' + segment.htmlTag + '>'; 
      break; 
     case 'MarkupEnd': 
      html += '</' + segment.htmlTag + '>'; 
      break; 
     default: 
      html += segment.text; 
     } 
    } while (arr.length); 

    return html; 
    }; 

    $messageSegment.parseHttpResponse = function(data) { 
    return $messageSegment.parse(data.body.messageSegments); 
    }; 

    return $messageSegment; 
} 

指令

sfChatter指令觀察其url屬性和,每當值改變,將作出$http請求,解析響應,並自動更新它自己的內部HTML。

angular.module('myApp') 
    .directive('sfChatter', sfChatterDirective); 

sfChatterDirective.$inject = ['$http', '$messageSegment']; 
function sfChatterDirective($http, $messageSegment) { 
    return { 
    restrict: 'E', 
    link: postLink 
    }; 

    function postLink(scope, iElement, iAttrs) { 
    iAttrs.$observe('url', function(value) { 
     var url = scope.$eval(value); 
     $http({ 
     url: url, 
     method: 'GET', 
     transformResponse: $messageSegment.parseHttpResponse 
     }).then(function(res) { 
     iElement.html(res.data); 
     }); 
    }); 
    } 
} 

使用

在您的應用程序,你會做這樣的事情<sf-chatter url="myUrl">,其中myUrl是一個範圍變量,告訴指令打什麼$http端點。

+0

哇,這太棒了!由於我以前從未使用'transformResponse',你能否提供一個看起來像什麼的例子?從我剛剛閱讀的文檔看來,它裏面有幾個選項。 – TheEks

+0

謝謝!我的答案中的'sfChatter'指令使用transformResponse。 –

+0

哈!完全錯過了。史詩。謝謝Shaun – TheEks

0

這裏有一點角魔法給你。控制器代碼(你需要注入$ SCE):

var markup = '' 
for(var i = 0; i < $scope.messageSegments.length; i++){ 
    // console.log(markup) 
    if($scope.messageSegments[i].type === 'MarkupBegin'){ 
    markup = markup + '<'+$scope.messageSegments[i].htmlTag+'>' 
    } 
    else if($scope.messageSegments[i].type === 'MarkupEnd'){ 
    markup = markup + '</'+$scope.messageSegments[i].htmlTag+'>' 
    } 
    else{ 
    markup = markup + $scope.messageSegments[i].text 
    } 
} 
$scope.markup = markup; 
$scope.markup = 
$sce.trustAsHtml(markup); 

而在HTML綁定這樣的:

<div ng-bind-html="markup"></div> 

Here是plunker。

相關問題