2014-07-16 10 views
6

Ho un problema interessante con la direttiva uiSref e non sono stato in grado di trovare una soluzione (benché elegante in ogni caso) ovunque sul web. Fondamentalmente ho un requisito da un client per poter fare clic su una riga in una tabella di risorse e andare alla vista di modifica per quella risorsa. Normalmente la direttiva uiSref funziona magnificamente, ma il problema risiede nel fatto che ho un dropdown Bootstrap nell'ultimo della tabella con un sacco di azioni rapide in esso. Il codice HTML simile a questa:UI-Router angolare ui-sref ignora alcuni elementi

<table class="table table-bordedered table-hover"> 
    <thead> 
    <tr> 
     <td>Name</td> 
     <td>Actions</td> 
    </tr> 
    </thead> 
    <tbody> 
    <tr ng-repeat="resource in resources" ui-sref="edit({id: resource.id})"> 
     <td ng-bind="resource.name"></td> 
     <td class="actions-column"> 
     <div class="btn btn-xs btn-default" data-toggle="dropdown"> 
      <i class="fa fa-cog"></i> 
     </div> 
     <ul class="dropdown-menu pull-right"> 
      <li> 
      <a href="javascript:void(0)" ng-click="doSomethingCrazy(resource)">SOMETHING CRAZY</a> 
      </li> 
     </ul> 
     </td> 
    </tr> 
    </tbody> 
</table> 

Il problema è che quando clicco sul pulsante nella colonna delle azioni, il uiSref sovrascrive l'azione predefinita del menu a discesa e mi porta alla pagina di modifica. Ora potresti chiederti "bene è facile, perché non puoi semplicemente interrompere la propagazione dell'evento!?" ... non funziona. Quando aggiungo questo alla colonna di azioni:

<td class="actions-column" ng-click="$event.stopPropagation()"> 

uccide la funzionalità del menu a discesa e non appare nulla. In questo momento ho una soluzione in luogo in cui mi definisco un ngClick sull'elemento <tr> che poi decifra in cui lo Stato dovrebbe andare a seconda dell'elemento cliccato in questo modo:

<tr ng-repeat="resource in resources" ng-click="goToEdit(resource, $event)"> 

And The JS si presenta così:

scope.goToEdit = function(resource, event) { 
    // if the event.target has parent '.actions-column' or is that column, do nothing else 
    // invoke $state.go('edit', {id: resource.id}) 
} 

Lo odio però e ho un sacco di visualizzazioni di lista come questo. Tutto quello che sto cercando è una soluzione elegante e portatile che si spera possa funzionare in modo nativo attraverso l'UI Router come $event.stopPropagation() (Anche se ho cercato attraverso l'origine del router UI e non riesco a trovare un'alternativa praticabile). Fondamentalmente voglio avere la mia torta e mangiarla anch'io. Ad ogni modo, sarà interessante vedere che cosa può fare la community SO o se ciò che sto chiedendo non è attualmente possibile. Grazie!

+0

più 1 per la domanda ben scritta e $ event.stopPropagation() che ha risolto il mio caso (utilizzo BUTTON, non A) –

risposta

6

Ho capito! Mentre guardi attraverso la sorgente del router UI un po 'di più, sembra che l'evento click verrà ignorato se l'attributo target viene popolato sull'elemento su cui si trova lo uiSref. Potrebbe non essere la cosa più bella del mondo, ma sicuramente è più facile di quello che stavo facendo prima.

NOTA: Questo funziona solo se si sta utilizzando l'intera libreria jQuery, non jQLite

Così ho scritto questa direttiva:

app.directive('uiSrefIgnore', function() { 
    return { 
    restrict: 'A', 
    link: function(scope, elem, attrs) { 
     elem.on('click', function(e) { 
     // Find the ui sref parent 
     var uiSref = elem.parents('[ui-sref]').first(); 
     // Set the target attribute so that the click event is ignored 
     uiSref.attr({ 
      target: 'true' 
     }); 
     // Function to remove the target attribute pushed to the bottom 
     // of the event loop. This allows for a digest cycle to be run 
     // and the uiSref element will be evaluated while the attribute 
     // is populated 
     setTimeout(function() { 
      uiSref.attr({ 
      target: null 
      }); 
     }, 0); 
     }); 
    } 
    }; 
}); 

In questo modo, ogni volta che voglio ignorare il javascript evento solo per la direttiva uiSref, posso solo aggiungere questo al codice HTML:

<tr ui-sref="edit"> 
    <!-- any other elements --> 
    <td ui-sref-ignore>The element I care about</td> 
</tr> 

BOOM! Fammi sapere cosa ne pensate voi ragazzi delle implicazioni di questo.

+1

si dovrebbe verificare questa soluzione: http://stackoverflow.com/questions/25070890/how- can-i-change-ng-clic-comportamento-per-un-singolo-elemento-in-un-ng-ripetizione –

+0

L'ho provato. stopPropagation stava uccidendo l'evento per il JavaScript a discesa di bootstrap – Mike

Problemi correlati