angularjs newline filter โดยไม่มี html อื่น ๆ


87

ฉันพยายามที่จะแปลงตัวอักษรขึ้นบรรทัดใหม่ ( \n) เป็น HTML br's
ตามการสนทนานี้ใน Google Groupนี่คือสิ่งที่ฉันได้รับ:

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

การอภิปรายยังแนะนำให้ใช้สิ่งต่อไปนี้ในมุมมอง:

{{ dataFromModel | newline | html }}

ดูเหมือนว่าจะใช้htmlตัวกรองเก่าในขณะที่ตอนนี้เราควรใช้ng-bind-htmlแอตทริบิวต์


ไม่ว่าสิ่งนี้จะทำให้เกิดปัญหา: ฉันไม่ต้องการให้ HTML ใด ๆ จากสตริงดั้งเดิม ( dataFromModel) แสดงผลเป็น HTML เฉพาะbrของ

ตัวอย่างเช่นกำหนดสตริงต่อไปนี้:

ในขณะที่ 7> 5
ฉันยังไม่ต้องการ html & ของที่นี่ ...

ฉันต้องการให้เอาต์พุต:

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

มีวิธีใดบ้างที่จะทำสิ่งนี้ให้สำเร็จ?

คำตอบ:


280

บางทีคุณสามารถบรรลุสิ่งนี้ได้ด้วย html เท่านั้น<preformated text>วิธี? มันจะหลีกเลี่ยงจากการใช้ตัวกรองหรือทำการประมวลผลใด ๆ

สิ่งที่คุณต้องทำคือแสดงข้อความภายในองค์ประกอบที่มี CSS นี้:

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

สิ่งนี้จะแยกวิเคราะห์และแสดง \ n เป็นบรรทัดใหม่ ใช้งานได้ดีสำหรับฉัน

นี่เป็นตัวอย่าง jsFiddle


79
พรีไลน์เป็นตัวเลือกที่ดีกว่าสำหรับฉัน
Pepijn

7
+1 นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุดและดูเหมือนว่าจะเหมาะกับความต้องการหลาย ๆ อย่าง อันที่จริงpre-lineน่าจะดีขึ้นในทั่วไปตั้งแต่แถวยาวจะถูกห่อ (ที่พวกเขาจะกับ<br>โซลูชั่นที่ใช้)
tuomassalo

13
style = "white-space: pre-line;" เป็นตัวเลือกที่ดีกว่าที่จะใช้ภายใน <div> ในความคิดของฉัน
Dmitri Algazin

7
pre-wrapดูเหมือนว่าจะเป็นสิ่งที่คนส่วนใหญ่ต้องการ (ไม่ใช่แบบล่วงหน้า): "ช่องว่างถูกเก็บรักษาไว้โดยเบราว์เซอร์ข้อความจะห่อเมื่อจำเป็นและเป็นตัวแบ่งบรรทัด" จากw3schools
qwertzguy

2
ฉันพบว่าฉันจำเป็นต้องใช้ ng-bind = "MyMultiLineText" บน <p> เพื่อหยุด Chrome เพิ่มบรรทัดพิเศษด้านหน้าข้อความของฉัน
Scott Warren

33

แทนที่จะยุ่งกับคำสั่งใหม่ฉันตัดสินใจใช้แค่ 2 ตัวกรอง:

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;');
    }
});

จากนั้นในมุมมองของฉันฉันต่อท่อเข้าอีกอัน:

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

regex ของคุณสำหรับบรรทัดใหม่จะไม่ทำงาน คุณต้องการ: text.replace(/\\n/g, '<br />')หรือดีกว่านั้นtext.replace(/(\\r)?\\n/g, '<br />')
Bartłomiej Zalewski

2
@BarthZalewski - คุณต้องการเฉพาะเมื่อรวบรวม regex จากสตริง เมื่อใช้ลิเทอรัล regex คุณไม่จำเป็นต้องขึ้นเครื่องหมายทับ
MegaHit

2
โค้ดนี้ใช้ไม่ได้อีกต่อไปเนื่องจากเลิกใช้งาน ng-bind-html-unsafe
Abhi

1
ตอนนี้คุณสามารถข้ามตัวกรอง noHtml ได้หากต้องการและเพิ่มตัวกรอง newLines เป็น ng-bind-html ngSanitize จะดูแลส่วนที่เหลือ
Dave Merwin

26

วิธีที่ง่ายกว่านี้คือการสร้างตัวกรองที่แยกข้อความ\nออกเป็นรายการจากนั้นใช้ `ng-repeat

ตัวกรอง:

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

และใน html:

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

4
ฉันชอบโซลูชันนี้ แต่จะไปกับ HTML ที่ง่ายกว่า:<p ng-repeat="line in (line.message | newlines)">{{line}}</p>
Thomas Fankhauser

2
คำตอบที่ดี แต่การใช้ที่ดีกว่าในกรณีของเส้นที่ซ้ำกันซึ่งจะยกข้อผิดพลาด:track by line in (text | newlines) track by $index
JellicleCat

11

หากคุณไม่ต้องการทำลายเค้าโครงด้วยสตริงที่ไม่มีที่สิ้นสุดให้ใช้ pre-line:

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

6

ฉันไม่ทราบว่า Angular มีบริการดึง html หรือไม่ แต่ดูเหมือนว่าคุณต้องลบ html ก่อนที่จะส่งผ่านnewlinesตัวกรองที่กำหนดเอง วิธีที่ฉันจะทำคือใช้no-htmlคำสั่งที่กำหนดเองซึ่งจะถูกส่งผ่านคุณสมบัติขอบเขตและชื่อของตัวกรองที่จะใช้หลังจากลบhtml

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

นี่คือการใช้งาน

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);
  };
});

บิตที่สำคัญคือtextตัวแปร ที่นี่ฉันสร้างองค์ประกอบ DOM ระดับกลางและต่อท้าย HTML โดยใช้htmlวิธีการจากนั้นดึงเฉพาะข้อความด้วยtextวิธีการ ทั้งสองวิธีมีให้โดยรุ่น Lite เชิงมุมของ jQuery

ส่วนต่อไปนี้คือการใช้newlineตัวกรองซึ่งทำได้โดยใช้$filterบริการ

ตรวจสอบ Plunker ที่นี่: http://plnkr.co/edit/SEtHH5eUgFEtC92Czq7T?p=preview


2

การอัปเดตตัวกรองด้วย ng-bind-html ในปัจจุบันจะเป็น:

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

และไม่จำเป็นต้องใช้ตัวกรอง noHTML อีกต่อไป

โซลูชันพื้นที่สีขาวมีการสนับสนุนเบราว์เซอร์ต่ำ: http://caniuse.com/#search=tab-size


0

ไปปาร์ตี้ช้าไปหน่อย แต่ฉันขอแนะนำให้ปรับปรุงเล็กน้อยเพื่อตรวจสอบสตริงที่ไม่ได้กำหนด / ว่าง

สิ่งที่ต้องการ:

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

หรือ (แน่นกว่าเล็กน้อย)

.filter('newlines', function () {
    return function(text) {
        return (text instanceof String || typeof text === "string") ? text.replace(/(&#13;)?&#10;/g, '<br/>') : text;
    };
})
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.