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

时间:2016-04-18 14:38:15

标签: javascript angularjs angularjs-directive

我有一个简单的指令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
  };
});

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

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

关于为什么会发生这种情况的任何想法?

更新

仅当指令与ui-sref

一起使用时才会出现此问题
<a app-external-link ui-sref="foo">Example</a>

Plunk here

1 个答案:

答案 0 :(得分:0)

我有2个可能的解决方案。

  1. event.stopImmediatePropagation()event.preventDefault()结合使用controller中的点击处理程序,以阻止当前页面网址更改。

    演示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

  3. 我更喜欢 2 ,因为我列出的原因是因为代码较少,而angularui-router可以将您的工作与您尝试的工作分开(而不是必须复制一些逻辑)。此外,我还没有真正测试过 1 ,这可能会影响我尚未见过的其他事情。如果您愿意这样做,它似乎确实有用。