我想在浏览器遵循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>
但是不起作用。
答案 0 :(得分:67)
这answer启发我创建一个指令,允许我中断最终改变状态的事件链。为方便起见,其他用途也会阻止在同一元素上执行ng-click。
<强>的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>
答案 1 :(得分:27)
您可以使用将返回的范围函数:
现有状态
像这样:HTML:
<li ui-sref-active="active">
<a ui-sref="{{checkCondition()}}">Go Somestate</a>
</li>
JS范围:
$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>
希望这有帮助
答案 2 :(得分:9)
有条件地实现路由而不修改指令,范围等的最简单的解决方法是我在这里找到的解决方法 - https://github.com/angular-ui/ui-router/issues/1489
<强> <a ui-sref="{{condition ? '.childState' : '.'}}"> Conditional Link </a>
强>
答案 3 :(得分:7)
您可以随时加倍元素并有条件地显示/隐藏
<li ui-sref-active="active">
<a ng-show="condition1" style="color: grey">Start</a>
<a ng-hide="condition1" ui-sref="start">Start</a>
</li>
答案 4 :(得分:3)
无需复杂的指令或黑客攻击。以下工作正常,并允许单击非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
}
};
答案 5 :(得分:2)
根据How to dynamically set the value of ui-sref
的答案,您可以在范围内创建一个用于构建网址的功能:
$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', [])
&#13;
<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>
&#13;
答案 6 :(得分:1)
我知道这是一个老问题,但为了将来的参考,我想提供一个替代解决方案,因为到目前为止我没有在任何答案中看到它。
<强>所需强>
<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');
}
}
答案 7 :(得分:0)
仍然需要ng-click
处理ui-sref
组件或其父级的人员的可能解决方案。
我的解决方案是使用href
代替ui-sref
并稍微修改Emanuel's指令,以便能够分别停止href
和ng-click
个调用。
虽然它有一些限制:
ui-sref
ui-sref-active
无法正常使用答案 8 :(得分:0)
对于二进制情况(链接被启用或禁用),它“现在”(自 2018 年起)的工作方式如下(防止点击并将其设置为禁用):
<a ui-sref="go" ng-disabled="true">nogo</a>
以及其他标签:
<span ui-sref="go" ng-disabled="true">nogo</span>