angularjs+ui.router:指令控制器和链接函数之间的不同行为

angularjs + ui.router: different behavior between directive controller and link functions

本文关键字:之间 函数 router 指令控制器 链接 angularjs+ui      更新时间:2023-09-26

我有一个简单的指令external-link,导致放置它的链接在一个单独的窗口中打开url,而不是当前的

<a app-external-link href="http://example.com">Example</a>

它类似于target="_blank",但能够跟踪用户何时点击它

为了这个例子,我删除了跟踪功能,所以它只需要表现得像target=_blank属性

angular.module('app', [])
.directive('appExternalLink', function ($window) {
  var link = function (scope, element, attrs) {
    element.on('click', function (event) {
      event.preventDefault();
      $window.open(attrs.href, '_blank');
    });
  };
  return {
    scope: true,
    link: link
  };
});

此实现如预期的那样工作。让我惊讶的是我使用的第一种方法是指令的控制器:

angular.module('app', [])
.directive('appExternalLink', function ($window) {
  var controller = function ($element, $attrs) {
    $element.on('click', function (event) {
      event.preventDefault();
      $window.open($attrs.href, '_blank');
    });
  };
  return {
    scope: true,
    controller: controller
  };
});

我不明白为什么(因此这个问题)在指令控制器中示例链接在新窗口中成功打开,但它也发生了更改新url的当前视图

就好像event.preventDefault()在这种情况下什么都不做

有什么想法吗?

更新:

该问题仅在指令与ui-sref 一起使用时发生

<a app-external-link ui-sref="foo">Example</a>

点击此处

我有两个潜在的解决方案。

  1. event.stopImmediatePropagation()event.preventDefault()组合用于controller中的单击处理程序,也可以阻止当前页面url的更改。

    演示:http://plnkr.co/edit/6Qi8NcWMmOvC4R3ZAqsf?p=info

  2. ui-sref已经可以与target="_blank"一起使用了,所以让您的指令只需将该属性添加到元素中,然后在单击处理程序中执行您想做的任何操作,甚至不必担心处理事件或使用window.open

    element.attr('target', '_blank');
    element.on('click', function (event) {
        //can track clicks or do whatever you want here
        console.log(attrs.href + ' opened in new tab.');
    });
    

    演示:http://plnkr.co/edit/brvftLiqXLznS6IWNmVA?p=info

我更喜欢2,因为我列出了一些原因,而且它的代码更少,而且它可以让angularui-router分别完成它们的工作,而不必重复一些逻辑。此外,我还没有真正测试1那么多,它可能会影响我还没有看到的其他东西。不过,如果你愿意这样做的话,它看起来确实有效。