繁体   English   中英

如何实现有条件地执行“ ui-sref”?

[英]How to achieve that “ui-sref” be conditionally executed?

我想在浏览器跟随ui-router动态创建的链接之前验证某些条件。

我当时在研究$rootscope.$on('$stateChangeStart', ..)但我无法从那里访问controller.$scope 我还需要在应用程序中的多个地方使用它,这会很麻烦。

请记住, ui-sref链接到ui-sref-active (共同工作),因此我无法删除ui-sref ,例如,不能在其中使用$state.$go('some-state')ng-click调用的函数。

该条件应在$scope functionon-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>

但是不起作用。

沙盒

这个答案激发了我创建一条指令,该指令使我可以中断一系列事件,这些事件最终导致状态改变。 为了方便起见和其他用途,也禁止在同一元素上执行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>

朋克

您可以使用范围函数,该函数将返回:

  • 没有状态
  • 现有状态

    像这样:

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>

希望这可以帮助

有条件地实现路由而不修改指令,范围等的最简单的解决方法是我在这里找到的解决方法-https: //github.com/angular-ui/ui-router/issues/1489

<a ui-sref="{{condition ? '.childState' : '.'}}"> Conditional Link </a>

您始终可以将元素加倍并有条件地显示/隐藏

    <li ui-sref-active="active">
          <a ng-show="condition1" style="color: grey">Start</a>
          <a ng-hide="condition1" ui-sref="start">Start</a>
    </li>

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

无需复杂的指令或黑客。 以下工作正常,并允许对非的点击具体经办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
  }
};

根据如何动态设置ui-sref的答案,您可以在范围内创建一个用于构建URL的函数:

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

然后有条件地将其附加到具有ng-href的链接

<a ng-href="{{ someCondition ? buildUrl() : undefined }}">Link</a>

如下面的演示所示,如果value为负,则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> 

我知道这是一个古老的问题,但是我想提供一个替代解决方案,因为到目前为止我在任何答案中都没有看到它,以供将来参考。

期望的:

<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并稍微修改Emanuel的指令以能够分别停止hrefng-click调用。

策划者

尽管有一些限制:

  • 不适用于ui-sref
  • 由于之前的限制,您应该为每个州使用不同的网址
  • ui-sref-active也不起作用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM