2014-07-16 13 views
6

Mam interesujący problem z dyrektywą uiSref i nie byłem w stanie znaleźć rozwiązania (dobrze i tak eleganckiego) w dowolnym miejscu w Internecie. Zasadniczo mam wymóg od klienta, aby móc kliknąć wiersz w tabeli zasobów i przejść do widoku edycji dla tego zasobu. Normalnie dyrektywa uiSref działa pięknie, ale problem polega na tym, że mam listę rozwijaną Bootstrap w ostatnim <td> tabeli z kilkoma szybkimi akcjami. HTML wygląda tak:Angular UI-router ignoruje niektóre elementy

<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> 

Problem polega na tym, że po kliknięciu na przycisk w kolumnie skargach uiSref zastępuje domyślne działanie rozwijanej i zabiera mnie do strony edycji. Teraz możesz zadawać sobie pytanie "dobrze, że to proste, dlaczego nie możesz po prostu zatrzymać propagacji wydarzenia!? ... nie działa. Gdy dodaję to do kolumny działań:

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

Zabija funkcjonalność menu rozwijanego i nic nie pokazuje. Teraz mam obejście w miejscu gdzie zdefiniować ngClick na elemencie <tr> które następnie rozszyfrowuje gdzie państwo powinno iść w zależności od elementu klikniętego tak:

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

I JS wygląda następująco:

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

Nienawidzę tego i mam wiele widoków listy w ten sposób. Wszystko, czego szukam, to eleganckie i przenośne rozwiązanie, które, mam nadzieję, działa natywnie za pośrednictwem routera UI, takiego jak $event.stopPropagation() (mimo tego, że przeszukałem źródło routera UI i nie mogę znaleźć możliwej do zastosowania alternatywy). Zasadniczo chcę mieć moje ciasto i je też. W każdym razie, będzie ciekawie zobaczyć, co może stworzyć społeczność SO lub czy to, o co pytam, nie jest obecnie możliwe. Dzięki!

+0

plus 1 za dobrze napisane pytanie i $ event.stopPropagation(), które rozwiązały moją sprawę (używam BUTTON, a nie A) –

Odpowiedz

6

Mam to! Podczas przeglądania źródła Routera UI trochę więcej, wydaje się, że zdarzenie kliknięcia zostanie zignorowane, jeśli atrybut target zostanie wypełniony na elemencie, który znajduje się na uiSref. To może nie być najpiękniejsza rzecz na świecie, ale z pewnością jest łatwiejsze niż to, co robiłem wcześniej.

UWAGA: ta działa tylko wtedy, gdy używasz całą bibliotekę jQuery, nie jQLite

Więc napisałem niniejszej dyrektywy:

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

ten sposób, gdy chcę, aby zignorować JavaScript impreza tylko dla dyrektywy uiSref, mogę tylko dodać do html:

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

BOOM! Daj mi znać, co myślicie o implikacjach tego.

+1

powinieneś sprawdzić to rozwiązanie: http://stackoverflow.com/questions/25070890/how- można zmienić zachowanie-kliknięcia-dla-pojedynczego elementu-w-powtórzenia-powtórzenia –

+0

Próbowałem tego. stopPropagation zabijało zdarzenie dla rozwijanego skryptu bootstrap JavaScript – Mike

Powiązane problemy