【问题标题】:Angular directive to replace external linksAngular 指令替换外部链接
【发布时间】:2016-02-27 01:42:40
【问题描述】:

如何创建自定义过滤器来替换:

<a href="http://www.externalsite.com">Whatever text</a>

进入这个:

<a href="#" ng-click="openExternal('http://www.externalsite.com')">Whatever text</a>

应该很容易,但我做不到……我有这个:

<div ng-bind-html="item.htmltext | myFilter"></div>

并且 item.htmltext 包含一些我想以这种方式替换的标签......我应该如何创建 myFilter 来替换链接?

【问题讨论】:

  • 我不记得如何从指令中获取参数,所以我不会回答。但是在指令中包含这样的 JS 代码不足以重定向吗? window.location = "http://www.yoururl.com";
  • 我忘了说我正在使用
    所以我的过滤器是我需要的......

标签: javascript html angularjs angularjs-directive


【解决方案1】:

编辑 2:

有一个没有$watch的解决方案:http://jsfiddle.net/33jQz/18/

指令优先级设置为-1(因为ngBindHtml的优先级为0),并使用$timeout服务在下一个$digest循环中运行逻辑。

编辑 1:

您可以使用指令替换 div 中的子 a 节点。它设置 $watch 检查 div 内新 &lt;a&gt; 元素的长度,然后剪切 href 属性并添加新属性 - ng-click="open()"。它在元素上使用$compile 服务来使ng-click 工作。

angular.module('ui.directives', []).directive('changeUrl', function ($compile) {
    return {
        restrict: 'A',
        scope: true,
        link: function (scope, elem, attrs) {

            scope.$watch(function () {
                return elem.children('a').length;
            }, function () {
                if (elem.children('a').length > 0) {
                    replace();
                }
            });

            function replace() {
                var href = elem.children('a').attr('href');
                elem.children('a').attr('href', null);
                elem.children('a').attr('ng-click', 'open(\''+href+'\')');
                $compile(elem.contents())(scope);

            }
            scope.open = function (url) {
                alert(url);
            }
        }
    }
});

由于使用了$watch,它应该可以与传递给 ng-bind-html 的外部 html 内容一起使用。

有一个jsfiddle:http://jsfiddle.net/33jQz/13/

旧答案:

您可以创建一个指令,将您的&lt;a href&gt; 替换为一个新指令

angular.module('ui.directives', []).directive('changeUrl', function () {
    return {
        restrict: 'A',
        scope: true,
        template: '<span><a ng-click="open()" ng-transclude></a></span>',
        replace: true,
        transclude: true,
        link: function (scope, elem, attrs) {
            var href = attrs.href;
            scope.open = function(){
                alert(href);    
            }
        }
    }
});

使用:

<a change-url href="http://www.externalsite.com">Whatever text</a>

JSFiddle:http://jsfiddle.net/33jQz/8/

【讨论】:

  • 问题是我无法将 change-url 添加到我的内容中。正如我所说,它是这样显示的:
    所以 item.htmltext 包含 html 数据(来自restangular)
  • 我已经更新了我的答案。它可能需要一些改进,但应该可以工作。
  • 它可以工作,但如果 HTML 文本包含大量链接,那就浪费了手表。没有办法只做一次吗?更换后可能会损坏手表吗?
  • ng-bind-html 的优先级为 0,因此您的指令应该稍后运行。您还必须使用$timeout 在下一个$digest 循环中呈现您的内容。有更新的小提琴没有$watch:jsfiddle.net/33jQz/18
【解决方案2】:

我找到了另一种使用 lodash 替换所有 a 标签元素的解决方案:

angular.module('module').directive('changeUrl', function ($compile, $timeout) {
return {
    priority: -1,
    restrict: 'A',
    scope: true,
    link: function (scope, elem, attrs) {
        $timeout(function() {
        var links = elem.find('a');
            _.map(links, function (a) {
                var href = a.href;
                a.setAttribute('ng-click', 'openUrl(\'' + href + '\')');
                a.removeAttribute('href');
            });
            $compile(elem.contents())(scope);
        });
    }
}

});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 2018-12-06
    • 2013-09-28
    相关资源
    最近更新 更多