Como conseguir que “ui-sref” seja executado condicionalmente?

Eu quero validar determinada condição antes do navegador seguir o link criado dinamicamente pelo ui-roteador.

Eu estava olhando para $rootscope.$on('$stateChangeStart', ..) mas eu não tenho access ao controller.$scope de lá. Eu também preciso usar isso em vários lugares no aplicativo e seria complicado.

Tenha em mente que o ui-sref está ligado ao ui-sref-active (trabalhe junto), então eu não posso remover o ui-sref e, por exemplo, usar $state.$go('some-state') dentro de um function chamada com ng-click .

A condição deve ser avaliada dentro de uma $scope function e no on-click event (antes da transição com a capacidade de cancelá-la)

Eu preciso de algo assim:

 
  • Go Somestate
  • Eu tentei:

     
  • Go Somestate
  • Go Somestate
  • E

     
  • Go Somestate
  • Até

     
  • Go Somestate
  • Mas não funciona.

    CAIXA DE AREIA

    Essa resposta me inspirou a criar uma diretiva que me permite interromper a cadeia de events que acabam mudando de estado. Por conveniência e outros usos também previne a execução de ng-click no mesmo elemento.

    javascript

     module.directive('eatClickIf', ['$parse', '$rootScope', function($parse, $rootScope) { return { // this ensure eatClickIf be compiled before ngClick priority: 100, restrict: 'A', compile: function($element, attr) { var fn = $parse(attr.eatClickIf); return { pre: function link(scope, element) { var eventName = 'click'; element.on(eventName, function(event) { var callback = function() { if (fn(scope, {$event: event})) { // prevents ng-click to be executed event.stopImmediatePropagation(); // prevents href event.preventDefault(); return false; } }; if ($rootScope.$$phase) { scope.$evalAsync(callback); } else { scope.$apply(callback); } }); }, post: function() {} } } } } ]); 

    html

     
  • Go Somestate
  • PLUNKER

    Você pode usar uma function de escopo que retornará:

    • sem estado
    • um estado existente

      igual a :

    HTML:

     
  • Go Somestate
  • Escopo JS:

     $scope.checkCondition = function() { return model.validate() ? 'someState' : '-' // hack: must return a non-empty string to prevent JS console error } 

    href atributo href será criado somente quando a function retornar uma string de estado existente.

    Alternativamente, você poderia fazer um (feio):

     
  • Go Somestate Go Somestate
  • Espero que isto ajude

    Você sempre pode dobrar o elemento e mostrar / ocultar condicionalmente

      
  • Start Start
  • http://plnkr.co/edit/ts4yGW?p=preview

    A maneira mais fácil de conseguir condicionalmente o roteamento sem mexer com diretivas, escopo, etc, foi uma solução alternativa que encontrei aqui – https://github.com/angular-ui/ui-router/issues/1489

    Conditional Link

    Com base nas respostas de Como definir dinamicamente o valor de ui-sref você pode criar uma function em seu escopo para criar o URL:

     $scope.buildUrl = function() { return $state.href('somestate', {someParam: 'someValue}); }; 

    E, em seguida, condicionalmente anexá-lo ao link com ng-href

     Link 

    Como você pode ver na demonstração abaixo, ng-href não adiciona o atributo href se o valor for negativo.

     angular.module('app', []) 
      
    This is the link

    Não há necessidade de diretivas ou hacks complicados. O seguinte funciona bem e permite um tratamento específico ao clicar em itens que não são sref :

     ... 

    E no controlador, um manipulador de cliques simples para os itens que não possuem um item.sref :

     this.click = function(item, event) { if (!item.sref) { event.preventDefault(); //do something else } }; 

    Eu sei que esta é uma questão antiga, mas para referência futura eu queria oferecer uma solução alternativa desde que eu não vi em nenhuma das respostas até agora.

    Desejado:

     
  • Go Somestate
  • Solução potencial (modelo):

     
  • Go Somestate
  • E no controlador:

     $scope.state = $state; $scope.navigateToState = navigateToState; function navigateToState() { if ($scope.model.valid) { $state.go('somestate'); } } 

    Possível solução para aqueles que ainda precisam de ng-click trabalhando no componente ui-sref ou seus pais.

    Minha solução é usar href vez de ui-sref e modificar um pouco a diretiva de Emanuel para poder parar as chamadas href e ng-click separadamente.

    Planker

    Embora tenha algumas restrições:

    • não funcionará com ui-sref
    • você deve ter URLs diferentes para cada estado devido à restrição anterior
    • ui-sref-active também não funciona