2016-02-09 10 views
7

Chcę pokazać kątową etykietę programu narzędziowego interfejsu użytkownika interfejsu użytkownika tylko w przypadku obcięcia tekstu. Próbowałem poniższy kod z dyrektywą niestandardowegoPokaż etykietkę narzędzia tylko wtedy, gdy tekst jest ucięty w ustawieniu kątowym interfejsu użytkownika interfejsu użytkownika

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

to działa dobrze w kątowym-UI-bootstrap wersji 0.12.1. Ale nowsze wersje tego nie wspierają.

Jak mogę osiągnąć tę samą funkcjonalność w najnowszej wersji kątowej-ui-bootstrap?

Z góry dziękuję za pomoc.

Odpowiedz

6

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

(Odpowiedź została zaktualizowana, aby odzwierciedlić sugestię do używania $ oglądać zamiast $ limit czasu, dzięki za komentarz Michael Mish Kisilenko!)

Przede wszystkim , zmień swoje instrukcje kątowe na zaktualizowane (przedrostek "uib-"):

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

n wykorzystać następującą dyrektywę, która dynamicznie zmienia kątową-ui przewidzianego cecha tooltip-enable (uwaga, że ​​należy zainicjować element z dyrektywą tooltip-enable="false" więc etykietka zostanie wyłączona, jeśli tekst nie jest obcinany:

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); 
     } 
     });*/ 
    } 
    }; 
}]); 

Aby obciąć tekst użyję zwykłego CSS:

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

lepszego i bardziej elastycznym rozwiązaniem byłoby prawdopodobnie doszło do zniweczenia „timeout” i wykorzystania zakres. $ obejrzyj element scrollWidth –

+0

@MichaelMishKisilenko rozwiązanie jest idealne, po prostu nie zapomnij go używać we właściwy sposób z [właściwość] (http://stackoverflow.com/questions/20403167/how-to-watch- property-in-attrs-of-directive) – aviram83

+0

@Sathya: Musimy wdrożyć to samo. Używamy szablonu komórki i nie możemy wyświetlić "uib-tooltip". Czy "uib-tooltip" nie jest kompatybilny z celltemplate lub czy masz jakieś obejście tego samego? –

0

Korzystanie z zegarka, o którym mowa w odpowiedzi wysłanej przez Lulu, obniży wydajność. Dodadzą tylu obserwatorom, ile ma siatek komórek, a te są oceniane w każdym cyklu trawienia.

zmodyfikowałem swój kod do wykorzystania podejścia mouseover - tak potrzeba podpowiedzi jest oceniany w przypadku przesunięć myszy tylko w określonej komórce:

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); 
    }); 
    } 
}); 
Powiązane problemy