Comment réaliser que" ui-sref " soit exécuté conditionnellement?
je veux valider certaines conditions avant que le navigateur ne suive le lien dynamiquement créé par ui-router.
je cherchais dans $rootscope.$on('$stateChangeStart', ..)
mais je n'ai pas accès au controller.$scope
de là. Je dois également utiliser ce à plusieurs endroits dans la demande et serait lourd.
Gardez à l'esprit que ui-sref
est lié à ui-sref-active
(travailler ensemble), donc je ne peux pas supprimer ui-sref
et, par exemple, utiliser $state.$go('some-state')
à l'intérieur d'une fonction appelée avec ng-click
.
la condition doit être évaluée à l'intérieur d'un $scope function
et sur on-click event
(avant-transition avec la possibilité de l'annuler)
j'ai besoin de quelque chose comme ceci:
<li ui-sref-active="active">
<a ui-sref="somestate" ui-sref-if="model.validate()">Go Somestate</a>
</li>
j'ai essayé:
<li ui-sref-active="active">
<a ui-sref="somestate" ng-click="$event.preventDefault()">Go Somestate</a>
</li>
<li ui-sref-active="active">
<a ui-sref="somestate" ng-click="$event.stopImmediatePropagation()">Go Somestate</a>
</li>
et
<li ui-sref-active="active">
<a ui-sref="somestate">
<span ng-click="$event.stopPropagation();">Go Somestate</span>
</a>
</li>
Pair
<li ui-sref-active="active">
<a ui-sref="somestate" onclick="return false;">Go Somestate</a>
</li>
Mais ne fonctionne pas.
8 réponses
Ce réponse m'a inspiré pour créer une directive qui me permet d'interrompre la chaîne des événements qui finissent par changer d'état. Pour la commodité et d'autres utilisations empêche également l'exécution de ng-click sur le même élément.
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
<li ui-sref-active="active">
<a ui-sref="somestate" eat-click-if="!model.isValid()">Go Somestate</a>
</li>
Vous pouvez utiliser une fonction qui renvoie :
- sans état
-
un état existant
comme ainsi:
HTML:
<li ui-sref-active="active">
<a ui-sref="{{checkCondition()}}">Go Somestate</a>
</li>
JS portée :
$scope.checkCondition = function() {
return model.validate()
? 'someState'
: '-' // hack: must return a non-empty string to prevent JS console error
}
L'attribut href
ne sera créé que si la fonction renvoie une chaîne d'état existante.
Alternativement, vous pourriez faire un (laid):
<li ui-sref-active="active">
<a ui-sref="somestate" ng-if="model.validate()">Go Somestate</a>
<span ng-if="!model.validate()">Go Somestate</span>
</li>
Espérons que cette aide
Vous pouvez toujours le double sur l'élément et afficher/masquer conditionnellement
<li ui-sref-active="active">
<a ng-show="condition1" style="color: grey">Start</a>
<a ng-hide="condition1" ui-sref="start">Start</a>
</li>
la solution de contournement la plus facile pour obtenir un routage conditionnel sans bricoler avec les directives, le champ d'application, etc était une solution de contournement que j'ai trouvé ici - https://github.com/angular-ui/ui-router/issues/1489
<a ui-sref="{{condition ? '.childState' : '.'}}"> Conditional Link </a>
basé sur les réponses à comment définir dynamiquement la valeur de ui-sref
vous pouvez créer une fonction dans votre portée pour construire L'URL:
$scope.buildUrl = function() {
return $state.href('somestate', {someParam: 'someValue});
};
et ensuite l'ajouter conditionnellement au lien avec ng-href
<a ng-href="{{ someCondition ? buildUrl() : undefined }}">Link</a>
comme vous pouvez le voir dans la démo ci-dessous, ng-href
n'ajoute pas l'attribut href
si la valeur est négative.
angular.module('app', [])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<a ng-href="{{ condition ? 'http://thecatapi.com/api/images/get?format=src&type=gif' : undefined}}">This is the link</a>
<br>
<label for="checkbox">
<input type="checkbox" id="checkbox" ng-model="condition">
Link active?
</label>
</div>
pas besoin de directives compliquées ou de piratages. Les travaux suivants très bien et permet une manipulation spécifique sur le clic de non - sref
articles:
<a
ng-repeat="item in items" ui-sref="{{item.sref || '-'}}"
ng-click="$ctrl.click(item, $event)"
>...</a>
et dans le contrôleur, un simple click handler pour les éléments qui n'ont pas de item.sref
:
this.click = function(item, event) {
if (!item.sref) {
event.preventDefault();
//do something else
}
};
je sais que c'est une vieille question, mais pour référence future je voulais offrir une solution alternative car je ne l'ai vu dans aucune des réponses jusqu'à présent.
désiré:
<li ui-sref-active="active">
<a ui-sref="somestate" ui-sref-if="model.validate()">Go Somestate</a>
</li>
solution (modèle):
<li ng-class="{ active: state.current.name === 'somestate' }">
<a ng-click="navigateToState()">Go Somestate</a>
</li>
et dans le contrôleur:
$scope.state = $state;
$scope.navigateToState = navigateToState;
function navigateToState() {
if ($scope.model.valid) {
$state.go('somestate');
}
}
solution Possible pour ceux qui auraient encore besoin de ng-click
travailler sur ui-sref
composant ou de ses parents.
ma solution est d'utiliser href
au lieu de ui-sref
et de modifier Emanuel's directive un peu pour pouvoir arrêter href
et ng-click
séparément.
Planker .
malgré quelques restrictions:
- ne fonctionnera pas avec
ui-sref
- vous devriez avoir des urls différentes pour chaque État en raison de la restriction précédente
-
ui-sref-active
ne fonctionnera pas non plus