Как добиться того, чтобы" ui-sref " был условно выполнен?
Я хочу проверить определенное условие, прежде чем браузер перейдет по ссылке, динамически созданной ui-router.
Я искал в $rootscope.$on('$stateChangeStart', ..)
но у меня нет доступа к controller.$scope
оттуда. Мне также нужно использовать это в нескольких местах в приложении и будет громоздким.
имейте в виду, что ui-sref
связан с ui-sref-active
(работаем вместе), поэтому я не могу удалить ui-sref
и, скажем, использовать $state.$go('some-state')
внутри функции, вызываемой с ng-click
.
условие должно быть оценено внутри $scope function
и on-click event
(перед переходом с возможностью его отмены)
мне нужно что-то вроде этого:
<li ui-sref-active="active">
<a ui-sref="somestate" ui-sref-if="model.validate()">Go Somestate</a>
</li>
пробовал:
<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>
и
<li ui-sref-active="active">
<a ui-sref="somestate">
<span ng-click="$event.stopPropagation();">Go Somestate</span>
</a>
</li>
даже
<li ui-sref-active="active">
<a ui-sref="somestate" onclick="return false;">Go Somestate</a>
</li>
но не работает.
8 ответов:
этой ответ вдохновил меня на создание директивы, которая позволяет мне прерывать цепочку событий, которые в конечном итоге изменяют состояние. Для удобства и других целей также предотвращает выполнение ng-нажмите на тот же элемент.
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>
вы можете использовать функцию scope, которая либо возвращает:
- нет государства
существующее состояние
вот так :
HTML:
<li ui-sref-active="active"> <a ui-sref="{{checkCondition()}}">Go Somestate</a> </li>
JS scope:
$scope.checkCondition = function() { return model.validate() ? 'someState' : '-' // hack: must return a non-empty string to prevent JS console error }
href
атрибут будет создан только тогда, когда функция возвращает существующую строку состояния.в качестве альтернативы, вы можете сделать (уродливый):
<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>
надеюсь, что это помогает
вы всегда можете удвоить элемент и показать / скрыть условно
<li ui-sref-active="active"> <a ng-show="condition1" style="color: grey">Start</a> <a ng-hide="condition1" ui-sref="start">Start</a> </li>
самый простой обходной путь для условного достижения маршрутизации без возни с директивами, областью действия и т. д. Был обходным путем, который я нашел здесь -https://github.com/angular-ui/ui-router/issues/1489
<a ui-sref="{{condition ? '.childState' : '.'}}"> Conditional Link </a>
на основе ответов на как динамически установить значение
ui-sref
вы можете создать функцию в вашей области для построения URL:$scope.buildUrl = function() { return $state.href('somestate', {someParam: 'someValue}); };
а затем условно добавить его к ссылке с
ng-href
<a ng-href="{{ someCondition ? buildUrl() : undefined }}">Link</a>
как вы можете видеть в демо ниже,
ng-href
не добавлятьhref
атрибута, если значение отрицательное.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>
нет необходимости в сложных директив или хаки. Следующие прекрасно работает и позволяет для конкретной обработки по щелчку не -
sref
детали:<a ng-repeat="item in items" ui-sref="{{item.sref || '-'}}" ng-click="$ctrl.click(item, $event)" >...</a>
и в контроллере, простой обработчик щелчка для элементов, которые не имеют
item.sref
:this.click = function(item, event) { if (!item.sref) { event.preventDefault(); //do something else } };
Я знаю, что это старый вопрос, но для дальнейшего использования я хотел бы предложить альтернативное решение, так как я не видел его ни в одном из ответов до сих пор.
желательно:
<li ui-sref-active="active"> <a ui-sref="somestate" ui-sref-if="model.validate()">Go Somestate</a> </li>
потенциальное решение (шаблон):
<li ng-class="{ active: state.current.name === 'somestate' }"> <a ng-click="navigateToState()">Go Somestate</a> </li>
и в контроллере:
$scope.state = $state; $scope.navigateToState = navigateToState; function navigateToState() { if ($scope.model.valid) { $state.go('somestate'); } }
возможное решение для тех, кто еще нужен
ng-click
работая наui-sref
компонент или его родителей.мое решение-использовать
href
вместоui-sref
и изменить Эмануэль директива немного, чтобы иметь возможность остановитьhref
иng-click
звонки отдельно.хотя у него есть несколько ограничений:
- не работает с
ui-sref
- вы должны иметь разные URL-адреса каждое государство из-за предыдущего ограничения
ui-sref-active
не работает