Bộ lọc dòng mới anglejs không có html khác


86

Tôi đang cố gắng chuyển đổi các ký tự dòng mới ( \n) thành html br.
Theo cuộc thảo luận này trong Nhóm Google , đây là những gì tôi có:

myApp.filter('newlines', function () {
    return function(text) {
        return text.replace(/\n/g, '<br/>');
    }
});

Cuộc thảo luận ở đó cũng khuyên sử dụng những điều sau đây trong chế độ xem:

{{ dataFromModel | newline | html }}

Điều này dường như đang sử dụng htmlbộ lọc cũ , trong khi bây giờ chúng tôi phải sử dụng ng-bind-htmlthuộc tính.


Bất kể, điều này đặt ra một vấn đề: Tôi không muốn bất kỳ HTML nào từ chuỗi gốc ( dataFromModel) được hiển thị dưới dạng HTML; chỉ có br.

Ví dụ, cho chuỗi sau:

Trong khi 7> 5,
tôi vẫn không muốn html và nội dung ở đây ...

Tôi muốn nó xuất ra:

While 7 &gt; 5<br>I still don't want html &amp; stuff in here...

Có cách nào để thực hiện điều này?

Câu trả lời:


279

Có lẽ bạn có thể đạt được điều này chỉ với html, một <preformated text>cách? Nó sẽ tránh sử dụng bộ lọc hoặc thực hiện bất kỳ loại xử lý nào.

Tất cả những gì bạn phải làm là hiển thị văn bản trong phần tử có CSS ​​này:

<p style="white-space: pre;">{{ MyMultiLineText}}</p>

Thao tác này sẽ phân tích cú pháp và hiển thị \ n dưới dạng các dòng mới. Làm việc tuyệt vời cho tôi.

Đây, một ví dụ về jsFiddle .


79
pre-line, là một lựa chọn tốt hơn cho tôi.
Pepijn

7
+1, đây là giải pháp đơn giản nhất và dường như phù hợp với nhiều nhu cầu. Thật vậy, pre-linenói chung có lẽ tốt hơn, vì các hàng dài sẽ được bao bọc (như chúng sẽ làm với bất kỳ <br>giải pháp dựa trên nào ).
tuomassalo

13
style = "white-space: pre-line;" là lựa chọn tốt hơn để sử dụng bên trong <div>, theo ý kiến ​​của tôi
Dmitri Algazin

7
pre-wrapcó vẻ là điều mà hầu hết mọi người đều muốn (không pre-line): "Khoảng trắng được bảo quản bằng trình duyệt văn bản sẽ quấn khi cần thiết, và trên ngắt dòng." từ w3schools
qwertzguy

2
Tôi tìm thấy tôi cần phải sử dụng ng-bind = "MyMultiLineText" trên <p> để ngăn chặn Chrome thêm dòng thêm vào đằng trước văn bản của tôi
Scott Warren

33

Thay vì làm rối tung các chỉ thị mới, tôi quyết định chỉ sử dụng 2 bộ lọc:

App.filter('newlines', function () {
    return function(text) {
        return text.replace(/\n/g, '<br/>');
    }
})
.filter('noHTML', function () {
    return function(text) {
        return text
                .replace(/&/g, '&amp;')
                .replace(/>/g, '&gt;')
                .replace(/</g, '&lt;');
    }
});

Sau đó, theo quan điểm của tôi, tôi kết hợp cái này với cái kia:

<span ng-bind-html-unsafe="dataFromModel | noHTML | newlines"></span>

Regex của bạn cho các dòng mới sẽ không hoạt động. Bạn cần: text.replace(/\\n/g, '<br />')hoặc thậm chí tốt hơntext.replace(/(\\r)?\\n/g, '<br />')
Bartłomiej Zalewski

2
@BarthZalewski - Bạn chỉ cần `\ 'khi biên dịch regex từ một chuỗi. Khi sử dụng một ký tự regex, bạn không phải thoát khỏi các dấu gạch chéo.
MegaHit

2
Mã này không còn hoạt động vì ng-bind-html-safe không được dùng nữa.
Abhi

1
Bây giờ bạn có thể bỏ qua bộ lọc noHtml nếu muốn và chỉ cần thêm bộ lọc Dòng mới vào ng-bind-html. ngSanifying sẽ lo phần còn lại.
Dave Merwin

26

Một cách đơn giản hơn để thực hiện việc này là tạo một bộ lọc chia văn bản ở mỗi \nthành một danh sách, sau đó sử dụng `ng-repeat.

Bộ lọc:

App.filter('newlines', function() {
  return function(text) {
    return text.split(/\n/g);
  };
});

và trong html:

<span ng-repeat="line in (text | newlines) track by $index">
    <p> {{line}}</p>
    <br>
</span>

4
Tôi như giải pháp này, nhưng sẽ đi với HTML đơn giản hơn:<p ng-repeat="line in (line.message | newlines)">{{line}}</p>
Thomas Fankhauser

2
Tốt câu trả lời, nhưng tốt hơn sử dụng track bytrong trường hợp dòng trùng lặp, mà sẽ nâng cao một lỗi: line in (text | newlines) track by $index.
JellicleCat

11

Nếu bạn không muốn phá hủy bố cục với các chuỗi vô tận, hãy sử dụng dòng trước:

<p style="white-space: pre-line;">{{ MyMultiLineText}}</p>

6

Tôi không biết liệu Angular có dịch vụ tách html hay không, nhưng có vẻ như bạn cần xóa html trước khi chuyển newlinesbộ lọc tùy chỉnh của mình . Cách tôi sẽ làm là thông qua một tùy chỉnhno-html chỉ thị , chỉ thị này sẽ được chuyển một thuộc tính phạm vi và tên của bộ lọc để áp dụng sau khi xóahtml

<div no-html="data" post-filter="newlines"></div>

Đây là cách triển khai

app.directive('noHtml', function($filter){
  return function(scope, element, attrs){
    var html = scope[attrs.noHtml];
    var text = angular.element("<div>").html(html).text();

    // post filter
    var filter = attrs.postFilter;
    var result = $filter(filter)(text);

    // apending html
    element.html(result);
  };
});

Bit quan trọng là textbiến. Ở đây, tôi tạo một phần tử DOM trung gian và nối nó vào HTML bằng htmlphương pháp này và sau đó chỉ truy xuất văn bản cótext phương thức. Cả hai phương pháp đều được cung cấp bởi phiên bản jQuery của Angular .

Phần sau đang áp dụng newline bộ lọc, được thực hiện bằng cách sử dụng $filterdịch vụ.

Kiểm tra plunker tại đây: http://plnkr.co/edit/SEtHH5eUgFEtC92Czq7T?p=preview


2

Bản cập nhật cho bộ lọc với ng-bind-html hiện sẽ là:

myApp.filter('newlines', function () {
  return function(text) {
    return text.replace(/(&#13;)?&#10;/g, '<br/>');
  }
});

và bộ lọc noHTML không còn cần thiết nữa.

giải pháp khoảng trắng đang hỗ trợ trình duyệt thấp: http://caniuse.com/#search=tab-size


0

Hơi muộn đối với bữa tiệc về điều này nhưng tôi sẽ đề xuất một cải tiến nhỏ để kiểm tra các chuỗi không xác định / null.

Cái gì đó như:

.filter('newlines', function () {
    return function(text) {
        return (text) ? text.replace(/(&#13;)?&#10;/g, '<br/>') : text;
    };
})

Hoặc (chặt hơn một chút)

.filter('newlines', function () {
    return function(text) {
        return (text instanceof String || typeof text === "string") ? text.replace(/(&#13;)?&#10;/g, '<br/>') : text;
    };
})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.