AngularJS将`<br>`渲染为文本而非换行符

51

我相信这个问题以前已经被问过,但我找不到答案。

我有一个AngularJS脚本,它从数据库中获取数据并将其渲染为内容。除了我试图在一些地方将一些单词连接起来并用换行符分隔之外,一切都正常。

 **in the script.js**
groupedList[aIndex].CATEGORY = existingCategory+'\n'+thisCategory;
groupedList[aIndex].CATEGORY = existingCategory+'<br>'+thisCategory;

如果我使用以上代码的第一行,我看不到任何东西,但渲染后的html中没有新行。如果我使用第二行,<br> 将被渲染为文本,输出结果如下:

Instinct<br>Media
替代
Instinct
Media

如果有帮助的话,我可以发布完整的脚本,但我猜可能有一些简单的东西我没看到。

更新 这是完整的JS代码:

function qCtrl($scope, $filter, $http, $timeout){

    $scope.getCategories = function(){$http.post('quote.cfc?method=getCategories').success(function(data) { $scope.categories = data; });   }
    $scope.getClassifications = function(){$http.post('quote.cfc?method=getClassifications').success(function(data) {   $scope.classifications = data;  }); }
    $scope.getIndustries = function(){$http.post('quote.cfc?method=getIndustries').success(function(data) { $scope.industries = data;   }); }
    $scope.getKeywords = function(){$http.post('quote.cfc?method=getKeywords').success(function(data) { $scope.keywords = data; }); }
    $scope.getSources = function(){$http.post('quote.cfc?method=getSources').success(function(data) {   $scope.sources = data;  }); }

    $scope.getAllQuotes = function(){$http.post('quote.cfc?method=getAllQuotesJoined').success(function(data) { $scope.allQuotes = data;    }); }

    $scope.initScopes = function (){
        $scope.getCategories();
        $scope.getClassifications();
        $scope.getIndustries();
        $scope.getKeywords();
        $scope.getSources();
        $scope.getAllQuotes();
    }   
    $scope.initScopes();

    // SEARCH QUOTES
    $scope.filteredQuotes = $scope.allQuotes;
    $scope.search = {searchField:''};

    $scope.searchQuote = function(){
        var filter = $filter('filter');
        var searchCrit = $scope.search;
        var newlist = $scope.allQuotes;
        var groupedList = [];
        var idList = [];
        newlist = filter(newlist,{TESTQUOTE:searchCrit.searchField});
        for(i=0;i<10;i++){
            aIndex = idList.contains(newlist[i].TESTIMONIALID);
            if(aIndex >= 0){
                thisKeyword = newlist[i].KEYWORD;
                thisClassification = newlist[i].CLASSIFICATION;
                thisCategory = newlist[i].CATEGORY;
                existingKeyword = groupedList[aIndex].KEYWORD;
                existingClassification = groupedList[aIndex].CLASSIFICATION;
                existingCategory = groupedList[aIndex].CATEGORY;
                if(thisKeyword != '' && existingKeyword.indexOf(thisKeyword) == -1){
                    groupedList[aIndex].KEYWORD = existingKeyword+' - '+thisKeyword;
                } 
                if(thisClassification != '' && existingClassification.indexOf(thisClassification) == -1){
                    groupedList[aIndex].CLASSIFICATION = existingClassification+' \n '+thisClassification;
                } 
                if(thisCategory != '' && existingCategory.indexOf(thisCategory) == -1){
                    groupedList[aIndex].CATEGORY = existingCategory+'<br>'+thisCategory;
                }               
            } else {
                idList.push(newlist[i].TESTIMONIALID);
                groupedList.push(newlist[i]);
            }
        }
        $scope.filteredQuotes = groupedList;
      }
}
Array.prototype.contains = function ( needle ) {
   for (j in this) {
       if (this[j] == needle) return j;
   }
   return -1;
}

这里是HTML

<div ng-repeat="q in filteredQuotes" class="well clearfix">
                        <h3>{{q.TITLE}}</h3>
                        <div class="row-fluid" style="margin-bottom:5px;">
                            <div class="span3 well-small whBG"><h4>Classification</h4>{{q.CLASSIFICATION}}</div>
                            <div class="span3 well-small whBG pipeHolder"><h4>Categories</h4>{{q.CATEGORY}}</div>
                            <div class="span3 well-small whBG"><h4>Key Words</h4>{{q.KEYWORD}}</div>
                            <div class="span3 well-small whBG"><h4>Additional</h4>Industry = {{q.INDUSTRY}}<br>Source = {{q.SOURCE}}</div>
                        </div>
                        <div class="well whBG">{{q.TESTQUOTE}}</div>
                        <div class="tiny">
                            Source comment : {{q.SOURCECOMMENT}}<br>
                            Additional Comment : {{q.COMMENT}}
                        </div>
                    </div>
                </div>

1
它可能会将CATEGORY输出为TextNode。 - Shmiddty
我猜那是真的,有没有办法在TextNode中换行? - Lance
所以我假设我们至少需要看到您设置的绑定。 - Shmiddty
我不相信有任何方法可以将换行符插入到TextNode中。 - Shmiddty
6个回答

58

你可以使用 \n 连接单词,然后将这个样式应用到容器的 div 上。

style="white-space: pre;"

更多信息可以在https://developer.mozilla.org/en-US/docs/Web/CSS/white-space找到。

<p style="white-space: pre;">
    This is normal text.
</p>
<p style="white-space: pre;">
    This 
  text 
  contains 
  new lines.
</p>


除了\n之外,CSS也需要来强制换行,这一点并不是显而易见的。不错。 - dmvianna
AngularJS 模态模板 UI-Bootstrap 文本消息。 - bbh
3
好的。我使用 white-space: pre-wrap; 来换行文本。 - iMalek
1
这是最好、最简单的答案。太多时候{{messageText}}需要简单的格式化,而这绝对是最简单的方法。它允许您根据每个消息自定义这些消息,而无需担心自定义css格式或html注入。 - rolinger
简单干净,对我来说完美地工作。谢谢! - Sarjerao Ghadage

41

我实际上正在使用ng-repeat。如果这有帮助的话,我已经在我的原始帖子中添加了所有代码。 - Lance
这会产生 <div ng-bind-html="Instinct<br>Media"></div> 但是没有任何渲染。我也尝试过 <div class="ng-bind-html: {{q.CATEGORY}};"></div> 但是没有成功。 - Lance
Angular的链接已经损坏。 - ganders
根据“迁移...”页面的说法:“ngBindHtmlUnsafe已被移除,取而代之的是ngBindHtml”。 - Jesse Chisholm
1
如果你最近遇到了 Attempting to use an unsafe value in a safe context. 错误,请查看这个答案:https://dev59.com/HGIk5IYBdhLWcg3wTcYr#25679834 - xabi_sides

25

你需要使用ng-bind-html-unsafe,如果你相信HTML源的可靠性,它将呈现出你放入其中的所有内容。

使用ng-bind-html-unsafe

如果你信任渲染中的HTML源,请使用此选项,它将呈现出你放入其中的原始输出。

<div><h4>Categories</h4><span ng-bind-html-unsafe="q.CATEGORY"></span></div>

用ng-bind-html实现OR

如果你不信任HTML的来源(例如用户输入),请使用此方法。它将对HTML进行清理以确保其不包含脚本标签或其他潜在安全风险的源。

请确保包含以下内容:

<script src="http://code.angularjs.org/1.0.4/angular-sanitize.min.js"></script>

然后在你的应用程序模块中引用它:

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

然后使用它:

<div><h4>Categories</h4><span ng-bind-html="q.CATEGORY"></span></div>

感谢@blesh,我选择了Shimiddy的回答作为最佳答案,因为他在过去的一个小时里一直在帮助我,但我会给你点赞。再次感谢。 - Lance
没问题。一开始他的回答有些困难,首先是使用了错误的指令,然后是没有正确地使用...即ng-bind-html="{{blah}}"。看起来你在我发布之前就解决了它。 - Ben Lesh
4
+1 我希望真正了解Angular的人能出现。哈哈。 - Shmiddty
1
我只是在旁观。回答那些我不完全知道答案的问题,我会学到更多。我能感觉到你已经掌握了大部分所需信息,并且你会得到答案。只是看起来你已经转移了注意力,所以我添加了一个答案。 - Ben Lesh

3

为什么这么复杂?

我用简单的方式解决了我的问题:

  <pre>{{existingCategory+thisCategory}}</pre>

如果字符串包含 '\n',那么在从文本区域保存数据时,它会自动创建 <br />

因为你的解决方案破坏了格式,所以它是 pre - ruX

2

我用的是这样的方式

function chatSearchCtrl($scope, $http,$sce) {
 // some more my code

// take this 
data['message'] = $sce.trustAsHtml(data['message']);

$scope.searchresults = data;

在HTML中,我做了以下操作:

<p class="clsPyType clsChatBoxPadding" ng-bind-html="searchresults.message"></p>

这就是我使用 <br/> 标签呈现的效果。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接