Limitare la lunghezza di una stringa con AngularJS


225

Ho il seguente:

<div>{{modal.title}}</div>

C'è un modo per limitare la lunghezza della stringa per dire 20 caratteri?

E una domanda ancora migliore sarebbe: c'è un modo in cui potrei cambiare la stringa per essere troncata e mostrarla ...alla fine se è più di 20 caratteri?


Risposte:


344

Modifica L'ultima versione del filtroAngularJS offerte .limitTo

È necessario un filtro personalizzato come questo:

angular.module('ng').filter('cut', function () {
        return function (value, wordwise, max, tail) {
            if (!value) return '';

            max = parseInt(max, 10);
            if (!max) return value;
            if (value.length <= max) return value;

            value = value.substr(0, max);
            if (wordwise) {
                var lastspace = value.lastIndexOf(' ');
                if (lastspace !== -1) {
                  //Also remove . and , so its gives a cleaner result.
                  if (value.charAt(lastspace-1) === '.' || value.charAt(lastspace-1) === ',') {
                    lastspace = lastspace - 1;
                  }
                  value = value.substr(0, lastspace);
                }
            }

            return value + (tail || ' …');
        };
    });

Uso:

{{some_text | cut:true:100:' ...'}}

Opzioni:

  • wordwise (booleano) - se vero, tagliato solo da limiti di parole,
  • max (numero intero) - lunghezza massima del testo, ridotta a questo numero di caratteri,
  • tail (string, default: '…') - aggiungi questa stringa alla stringa di input se la stringa è stata tagliata.

Un'altra soluzione : http://ngmodules.org/modules/angularjs-truncate (di @Ehvince)


2
C'è un equivalente nei moduli angolari: ngmodules.org/modules/angularjs-truncate
Ehvince

angularjs-truncate non è una soluzione, ma la tua soluzione IS. Grazie! Fallo come modulo!
Anton Bessonov,

@epokk C'è un modo per consentire all'utente, dopo aver fatto clic sui tre punti, di mostrare il testo integrale non tagliato? Ti piace uno "mostra di più"? Grazie!
Thales P

funziona benissimo quando lo usiamo in questo modo {{post.post_content | cut: true: 100: '...'}} Ma fallisco quando uso in questo modo <span ng-bind-html = "trustedHtml (post.post_content | cut: true: 100: '...')"> < / span> Perché nel mio caso sono costretto a usarlo con html di fiducia
S Vinesh,

Il limite di parole è una bella funzionalità che sembra non esistere nel "limite di default"
pdizz

496

Ecco la semplice correzione di una riga senza CSS.

{{ myString | limitTo: 20 }}{{myString.length > 20 ? '...' : ''}}

79
Semplice ed elegante. Invece di '...'te puoi anche usare l'entità HTML per i puntini di sospensione:'&hellip;'
Tom Harrison,

probabilmente la soluzione più indolore. Tieni ancora presente che i filtri sono relativamente pesanti e questo potrebbe avere problemi di prestazioni in un enorme elenco di ripetizioni! :)
Cowwando,

1
eccezionale! c'è un modo per tagliare dopo un numero di righe, piuttosto che dopo un numero di caratteri?
axd,

@axd Devi provarlo in css o scrivere una direttiva per farlo.
Govan,

1
Questa è la risposta migliore Il colpo di prestazione dovrebbe essere trascurabile con un numero ragionevole di ng-repeat. Se stai riportando centinaia di ng-repeat con contenuti che devono essere troncati, potrebbe essere necessario tornare al tavolo da disegno. Bella risposta, @Govan
erier,

59

So che è in ritardo, ma nell'ultima versione di angularjs (sto usando 1.2.16) il filtro limitTo supporta sia le stringhe che le matrici in modo da poter limitare la lunghezza della stringa in questo modo:

{{ "My String Is Too Long" | limitTo: 9 }}

che produrrà:

My String

9
In questa soluzione manca il "...". Il risultato dovrebbe essere: "My String ..."
Snæbjørn

Non vedo i puntini di sospensione qui: plnkr.co/edit/HyAejS2DY781bqcT0RgV?p=preview . Puoi elaborare?
magro,

2
Quello che @ Snæbjørn sta dicendo è che la persona che ha posto la domanda ha preferito una soluzione che inserisce "..." alla fine della stringa troncata. La risposta di Govan lo fa.
Nahn,

@Nahn grazie per averlo sottolineato. Probabilmente avrei dovuto fare un commento alla risposta di EpokK anziché un'altra risposta.
magro

52

Puoi semplicemente aggiungere una classe css al div e aggiungere un suggerimento tramite angularjs in modo che il testo ritagliato sia visibile al passaggio del mouse.

<div class="trim-info" tooltip="{{modal.title}}">{{modal.title}}</div>

   .trim-info {
      max-width: 50px;
      display: inline-block;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;  
      line-height: 15px;
      position: relative;
   }

4
overflow del testo: puntini di sospensione, bello.
Chris Russo,

4
questa tecnica, sebbene eccezionale, impedisce al testo di essere a capo
Larry

Questa è la risposta corretta La mia regola generale è: "non fare in JavaScript ciò che può essere fatto in CSS".
Aidan il

4
Funziona solo per il testo con una riga per paragrafo. Consultare multiline css-tricks.com/line-clampin (non tutti i browser lo supportano).
Robert,

Questo funziona anche se stai cercando di limitare la lunghezza di un array ng-repeat.
Chakeda,

27

Ho avuto un problema simile, ecco cosa ho fatto:

{{ longString | limitTo: 20 }} {{longString.length < 20 ? '' : '...'}}

Vorrei rimuovere lo spazio bianco tra le due uscite per evitare l'interruzione di linea
Ignacio Vazquez,

21
< div >{{modal.title | limitTo:20}}...< / div>

Approccio più semplice, ma funzionale. Ma si presume che ogni titolo avrebbe più di 20 caratteri e questo, in alcuni casi, potrebbe essere inaspettato.
Henrique M.,

18

Soluzione più elegante:

HTML:

<html ng-app="phoneCat">
  <body>
    {{ "AngularJS string limit example" | strLimit: 20 }}
  </body>
</html>

Codice angolare:

 var phoneCat = angular.module('phoneCat', []);

 phoneCat.filter('strLimit', ['$filter', function($filter) {
   return function(input, limit) {
      if (! input) return;
      if (input.length <= limit) {
          return input;
      }

      return $filter('limitTo')(input, limit) + '...';
   };
}]);

demo:

http://code-chunk.com/chunks/547bfb3f15aa1/str-limit-implementation-for-angularjs


Posso suggerire di aggiungere un ritorno nel caso in cui il inputvalore sia dinamico? cioè if (!input) {return;}Altrimenti ci saranno errori della console JS
mcranston18

1
@ mcranston18 aggiunto. Grazie.
Anam,

15

Poiché abbiamo bisogno dei puntini di sospensione solo quando la lunghezza della stringa supera il limite, sembra più appropriato aggiungere i puntini di sospensione utilizzando la ng-ifrilegatura.

{{ longString | limitTo: 20 }}<span ng-if="longString.length > 20">&hellip;</span>

7

C'è un'opzione

.text {
            max-width: 140px;
            white-space: nowrap;
            overflow: hidden;
            padding: 5px;
            text-overflow: ellipsis;(...)
        }
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi qui soluta labore! Facere nisi aperiam sequi dolores voluptatum delectus vel vero animi, commodi harum molestias deleniti, quasi nesciunt. Distinctio veniam minus ut vero rerum debitis placeat veritatis doloremque laborum optio, nemo quibusdam ad, sed cum quas maxime hic enim sint at quos cupiditate qui eius quam tempora. Ab sint in sunt consequuntur assumenda ratione voluptates dicta dolor aliquid at esse quaerat ea, veritatis reiciendis, labore repellendus rem optio debitis illum! Eos dignissimos, atque possimus, voluptatibus similique error. Perferendis error doloribus harum enim dolorem, suscipit unde vel, totam in quia mollitia.</div>


7

La soluzione più semplice che ho trovato per limitare semplicemente la lunghezza della stringa era {{ modal.title | slice:0:20 }}, e quindi prendere in prestito da @Govan sopra puoi usare {{ modal.title.length > 20 ? '...' : ''}}per aggiungere i punti di sospensione se la stringa è più lunga di 20, quindi il risultato finale è semplicemente:

{{ modal.title | slice:0:20 }}{{ modal.title.length > 20 ? '...' : ''}}

https://angular.io/docs/ts/latest/api/common/index/SlicePipe-pipe.html


4

Ecco un filtro personalizzato per troncare il testo. È ispirato alla soluzione di EpokK ma modificato per le mie esigenze e gusti.

angular.module('app').filter('truncate', function () {

    return function (content, maxCharacters) {

        if (content == null) return "";

        content = "" + content;

        content = content.trim();

        if (content.length <= maxCharacters) return content;

        content = content.substring(0, maxCharacters);

        var lastSpace = content.lastIndexOf(" ");

        if (lastSpace > -1) content = content.substr(0, lastSpace);

        return content + '...';
    };
});

Ed ecco i test unitari in modo da poter vedere come dovrebbe comportarsi:

describe('truncate filter', function () {

    var truncate,
        unfiltered = " one two three four ";

    beforeEach(function () {

        module('app');

        inject(function ($filter) {

            truncate = $filter('truncate');
        });
    });

    it('should be defined', function () {

        expect(truncate).to.be.ok;
    });

    it('should return an object', function () {

        expect(truncate(unfiltered, 0)).to.be.ok;
    });

    it('should remove leading and trailing whitespace', function () {

        expect(truncate(unfiltered, 100)).to.equal("one two three four");
    });

    it('should truncate to length and add an ellipsis', function () {

        expect(truncate(unfiltered, 3)).to.equal("one...");
    });

    it('should round to word boundaries', function () {

        expect(truncate(unfiltered, 10)).to.equal("one two...");
    });

    it('should split a word to avoid returning an empty string', function () {

        expect(truncate(unfiltered, 2)).to.equal("on...");
    });

    it('should tolerate non string inputs', function () {

        expect(truncate(434578932, 4)).to.equal("4345...");
    });

    it('should tolerate falsey inputs', function () {

        expect(truncate(0, 4)).to.equal("0");

        expect(truncate(false, 4)).to.equal("fals...");
    });
});

3

È possibile limitare la lunghezza di una stringa o di un array utilizzando un filtro. Controlla questo scritto dal team di AngularJS.


fornisci anche qualche dettaglio in più
Parixit,

3

In html viene utilizzato insieme a limitTo filter fornito dall'angolo stesso come di seguito ,

    <p> {{limitTo:30 | keepDots }} </p>

filtro keepDots:

     App.filter('keepDots' , keepDots)

       function keepDots() {

        return function(input,scope) {
            if(!input) return;

             if(input.length > 20)
                return input+'...';
            else
                return input;

        }


    }

3

Se vuoi qualcosa del tipo: InputString => StringPart1 ... StringPart2

HTML:

<html ng-app="myApp">
  <body>
    {{ "AngularJS string limit example" | strLimit: 10 : 20 }}
  </body>
</html>

Codice angolare:

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

 myApp.filter('strLimit', ['$filter', function($filter) {
   return function(input, beginlimit, endlimit) {
      if (! input) return;
      if (input.length <= beginlimit + endlimit) {
          return input;
      }

      return $filter('limitTo')(input, beginlimit) + '...' + $filter('limitTo')(input, -endlimit) ;
   };
}]);

Esempio con i seguenti parametri:
beginLimit = 10
endLimit = 20

Prima : - /home/house/room/etc/ava_B0363852D549079E3720DF6680E17036.jar
Dopo : - /home/hous...3720DF6680E17036.jar


2
Use this in your html - {{value | limitTocustom:30 }}

and write this custom filter in your angular file,

app.filter('limitTocustom', function() {
    'use strict';
    return function(input, limit) {
        if (input) {
            if (limit > input.length) {
                return input.slice(0, limit);
            } else {
                return input.slice(0, limit) + '...';
            }
        }
    };
});

// if you initiate app name by variable app. eg: var app = angular.module('appname',[])

2

Questo potrebbe non essere dalla fine dello script, ma puoi usare i css seguenti e aggiungere questa classe al div. Questo troncerà il testo e mostrerà anche il testo completo al passaggio del mouse. È possibile aggiungere un altro testo e aggiungere un clickler angolare per modificare la classe di div su cli

.ellipseContent {
    overflow: hidden;
    white-space: nowrap;
    -ms-text-overflow: ellipsis;
    text-overflow: ellipsis;
}

    .ellipseContent:hover {
        overflow: visible;
        white-space: normal;
    }

2

Se hai due attacchi {{item.name}}e {{item.directory}}.

E vuoi mostrare i dati come una directory seguita dal nome, assumendo "/ root" come directory e "Machine" come nome (/ root-machine).

{{[item.directory]+[isLast ? '': '/'] + [ item.name]  | limitTo:5}}

C'è qualche possibilità che tu abbia pubblicato questa risposta sulla domanda sbagliata? Questo non sembra avere nulla a che fare con la limitazione della lunghezza di una stringa con AngularJS.
BSMP


1
<div>{{modal.title | slice: 0: 20}}</div>

0

Ho creato questa direttiva che lo fa facilmente, tronca la stringa a un limite specificato e aggiunge un interruttore "mostra più / meno". Puoi trovarlo su GitHub: https://github.com/doukasd/AngularJS-Components

può essere usato in questo modo:

<p data-dd-collapse-text="100">{{veryLongText}}</p>

Ecco la direttiva:

// a directive to auto-collapse long text
app.directive('ddCollapseText', ['$compile', function($compile) {
return {
    restrict: 'A',
    replace: true,
    link: function(scope, element, attrs) {

        // start collapsed
        scope.collapsed = false;

        // create the function to toggle the collapse
        scope.toggle = function() {
            scope.collapsed = !scope.collapsed;
        };

        // get the value of the dd-collapse-text attribute
        attrs.$observe('ddCollapseText', function(maxLength) {
            // get the contents of the element
            var text = element.text();

            if (text.length > maxLength) {
                // split the text in two parts, the first always showing
                var firstPart = String(text).substring(0, maxLength);
                var secondPart = String(text).substring(maxLength, text.length);

                // create some new html elements to hold the separate info
                var firstSpan = $compile('<span>' + firstPart + '</span>')(scope);
                var secondSpan = $compile('<span ng-if="collapsed">' + secondPart + '</span>')(scope);
                var moreIndicatorSpan = $compile('<span ng-if="!collapsed">...</span>')(scope);
                var toggleButton = $compile('<span class="collapse-text-toggle" ng-click="toggle()">{{collapsed ? "less" : "more"}}</span>')(scope);

                // remove the current contents of the element
                // and add the new ones we created
                element.empty();
                element.append(firstSpan);
                element.append(secondSpan);
                element.append(moreIndicatorSpan);
                element.append(toggleButton);
            }
        });
    }
};
}]);

E alcuni CSS per andare con esso:

.collapse-text-toggle {
font-size: 0.9em;
color: #666666;
cursor: pointer;
}
.collapse-text-toggle:hover {
color: #222222;
}
.collapse-text-toggle:before {
content: '\00a0(';
}
.collapse-text-toggle:after {
content: ')';
}

0

Questa soluzione utilizza esclusivamente tag ng su HTML.

La soluzione è limitare il testo lungo visualizzato con il link "mostra altro ..." alla fine. Se l'utente fa clic sul link "mostra altro ...", mostrerà il resto del testo e rimuoverà il link "mostra altro ...".

HTML:

<div ng-init="limitText=160">
   <p>{{ veryLongText | limitTo: limitText }} 
       <a href="javascript:void(0)" 
           ng-hide="veryLongText.length < limitText" 
           ng-click="limitText = veryLongText.length + 1" > show more..
       </a>
   </p>
</div>

0

LA SOLUZIONE PIÙ SEMPLICE -> ho scoperto è lasciare che Material Design (1.0.0-rc4) faccia il lavoro. La md-input-containerfarà il lavoro per voi. Concatena la stringa e aggiunge ellissi, inoltre ha il vantaggio extra di permetterti di fare clic per ottenere il testo completo in modo che sia l'intera enchilada. Potrebbe essere necessario impostare la larghezza di md-input-container.

HTML:

<md-input-container>
   <md-select id="concat-title" placeholder="{{mytext}}" ng-model="mytext" aria-label="label">
      <md-option ng-selected="mytext" >{{mytext}}
      </md-option>
   </md-select>
</md-input-container>

CS:

#concat-title .md-select-value .md-select-icon{
   display: none; //if you want to show chevron remove this
}
#concat-title .md-select-value{
   border-bottom: none; //if you want to show underline remove this
}

0

Limitare il numero di parole con un filtro angolare personalizzato: ecco come ho usato un filtro angolare per limitare il numero di parole visualizzate utilizzando un filtro personalizzato.

HTML:

<span>{{dataModelObject.TextValue | limitWordsTo: 38}} ......</span>

Codice angolare / Javascript

angular.module('app')
.filter('limitWordsTo', function () {
    return function (stringData, numberOfWords) {
        //Get array of words (determined by spaces between words)
        var arrayOfWords = stringData.split(" ");

        //Get loop limit
        var loopLimit = numberOfWords > arrayOfWords.length ? arrayOfWords.length : numberOfWords;

        //Create variables to hold limited word string and array iterator
        var limitedString = '', i;
        //Create limited string bounded by limit passed in
        for (i = 0; i < loopLimit; i++) {
            if (i === 0) {
                limitedString = arrayOfWords[i];
            } else {
                limitedString = limitedString + ' ' + arrayOfWords[i];
            }
        }
        return limitedString;
    }; 
}); //End filter

0

Funziona bene per me 'In span', ng-show = "MyCtrl.value. $ ViewValue.length> your_limit" ... leggi di più. 'end span'


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.