2016-02-09 29 views
7

Voglio mostrare il suggerimento bootsrap dell'interfaccia utente angolare solo quando il testo viene troncato. Ho provato il codice qui sotto con la direttiva personalizzatoMostra descrizione solo quando il testo viene troncato nella direttiva bootstrap UI angolare

<div tooltip="{{value}}" tooltip-append-to-body="true" enable-truncate-tooltip>{{value}}</div> 

.directive("enableTruncateTooltip", function() { 
    return { 
    restrict: 'A', 
    link: function (scope, elem, attr) { 
     elem.bind('mouseenter', function() { 
     var $this = angular.element(this); 

     if (this.offsetWidth >= this.scrollWidth) { 
      angular.element('.tooltip').attr('hide-tooltip', true); 
     } 
     }); 
    } 
    } 
}) 

Funziona bene in angolare-ui-bootstrap versione 0.12.1 . Ma le versioni successive non supportano questo.

Come posso ottenere questa stessa funzionalità nell'ultima versione di angular-ui-bootstrap?

Grazie in anticipo per il vostro aiuto.

risposta

6

TL; DR: Plunker Demo (using $watch) Old demo (using $timeout)

(La risposta è stata aggiornata per riflettere un suggerimento di usare $ guardare invece di $ timeout, grazie per il commento Michael Mish Kisilenko!)

Prima di tutto , modificare le direttive angolare-ui a quelli aggiornati (prefisso con 'uib-'):

<div uib-tooltip="{{value}}" show-tooltip-on-text-over-flow tooltip-enable="false">{{value}}</div> 

E il n utilizzare la seguente direttiva, che cambia in modo dinamico l'angolare-ui fornito funzione tooltip-enable (nota che si dovrebbe inizializzare l'elemento alla direttiva tooltip-enable="false" in modo che il tooltip verrà disabilitata se il testo non viene troncato:

myApp.directive("showTooltipOnTextOverflow", ["$timeout", function($timeout) { 
    return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 
     var el = element[0]; 
     scope.$watch(function(){ 
     return el.scrollWidth; 
     }, function() { 
     var el = element[0]; 
     if (el.offsetWidth < el.scrollWidth) { 
      //console.log('ellipsis is active for element', element); 
      attrs.tooltipEnable = "true"; 
     } else { 
      //console.log('ellipsis is NOT active for element', element); 
     } 
     }); 
     /*$timeout(function() { 
     var el = element[0]; 
     if (el.offsetWidth < el.scrollWidth) { 
      //console.log('ellipsis is active for element', element); 
      attrs.tooltipEnable = "true"; 
     } else { 
      //console.log('ellipsis is NOT active for element', element); 
     } 
     });*/ 
    } 
    }; 
}]); 

troncare il testo userò semplicemente CSS:

span.truncated { 
    width: 400px; 
    white-space: nowrap; 
    overflow: hidden; 
    text-overflow: ellipsis; 
} 
+1

Una soluzione migliore e più flessibile sarebbe probabilmente di perdere il "timeout" e l'uso $ guarda sopra scrollWidth dell'elemento –

+0

@MichaelMishKisilenko la soluzione è perfetta, non dimenticarti di usarla nel modo giusto con [proprietà] (http://stackoverflow.com/questions/20403167/how-to-watch- property-in-attrs-of-directive) – aviram83

+0

@Sathya: Dobbiamo implementare la stessa cosa. Stiamo utilizzando il modello di cella e non siamo in grado di visualizzare "uib-tooltip" in primo luogo. "Uib-tooltip" non è compatibile con Celltemplate o hai qualche soluzione alternativa per lo stesso? –

0

L'uso dell'orologio come menzionato nella risposta inviata da Lulu porterà a una riduzione delle prestazioni. Aggiungerà così tanti osservatori quante più celle ha e queste vengono valutate in ogni ciclo di digestione.

ho modificato il suo codice per utilizzare approccio mouseover - quindi la necessità di tooltip viene valutato nel caso in mouseover solo in cella particolare:

myApp.directive("showTooltipOnTextOverflow", ["$timeout", function($timeout) { 
    return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 
     var el = element[0]; 

     if (angular.isObject(el)) { 
     var evaluateTooltip = (event: JQueryEventObject, isOurEvent: boolean) => { 
     // evaluate whether to enable tooltip 
     attrs.tooltipEnable = el.offsetWidth < el.scrollWidth ? "true" : "false"; 

     if (isOurEvent !== true && attrs.tooltipEnable === "true") { 
      // tooltip should be enabled, trigger mouseover again to trigger tooltip (current mouseover is already handled by tooltip with false value) 
      // and mark it as our event to avoid its handling here 
      element.trigger("mouseover", [true]); 

      // revert tooltip enabling back to false to cover case when mouseover happens and tooltip should not be enabled 
      scope.$applyAsync(() => { 
      attrs.tooltipEnable = "false"; 
     }); 
     } 
    }; 

    element.on("mouseover", evaluateTooltip); 

    element.on("$destroy",() => { 
     element.off("mouseover", evaluateTooltip); 
    }); 
    } 
});