我如何在angularjs中创建一个指令,例如接受这个元素:
<div>Example text http://example.com</div>
并将其转换为此
<div>Example text <a href="http://example.com">http://example.com</a></div>
我已经编写了自动链接函数中文本的函数并返回html(让我们调用函数“autoLink”)但是我的指令并没有达到标准。
我还想在元素中添加一个属性,将对象传递给指令。 e.g。
<div linkprops="link.props" >Example text http://example.com</div>
其中link.props是像{a:'bla bla',b:'waa waa'}这样的对象,它将作为第二个参数传递给autoLink函数(第一个是文本)。
答案 0 :(得分:38)
两种方式:
app.directive('parseUrl', function () {
var urlPattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/gi;
return {
restrict: 'A',
require: 'ngModel',
replace: true,
scope: {
props: '=parseUrl',
ngModel: '=ngModel'
},
link: function compile(scope, element, attrs, controller) {
scope.$watch('ngModel', function (value) {
var html = value.replace(urlPattern, '<a target="' + scope.props.target + '" href="$&">$&</a>') + " | " + scope.props.otherProp;
element.html(html);
});
}
};
});
HTML:
<p parse-url="props" ng-model="text"></p>
app.filter('parseUrlFilter', function () {
var urlPattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/gi;
return function (text, target, otherProp) {
return text.replace(urlPattern, '<a target="' + target + '" href="$&">$&</a>') + " | " + otherProp;
};
});
HTML:
<p ng-bind-html-unsafe="text | parseUrlFilter:'_blank':'otherProperty'"></p>
注意:'otherProperty'
仅作为示例,以防您想要将更多属性传递到过滤器中。
<强> jsFiddle 强>
更新:改进了替换算法。
答案 1 :(得分:5)
要回答这个问题的前半部分,没有额外的属性要求,可以使用Angular的linky过滤器:https://docs.angularjs.org/api/ngSanitize/filter/linky
答案 2 :(得分:4)
如果有多个链接,则最高投票的答案无效。 Linky已经为我们完成了90%的工作,唯一的问题是它清理了html,从而删除了html / newlines。我的解决方案是只编辑linky过滤器(下面是Angular 1.2.19)以不清理输入。
app.filter('linkyUnsanitized', ['$sanitize', function($sanitize) {
var LINKY_URL_REGEXP =
/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,
MAILTO_REGEXP = /^mailto:/;
return function(text, target) {
if (!text) return text;
var match;
var raw = text;
var html = [];
var url;
var i;
while ((match = raw.match(LINKY_URL_REGEXP))) {
// We can not end in these as they are sometimes found at the end of the sentence
url = match[0];
// if we did not match ftp/http/mailto then assume mailto
if (match[2] == match[3]) url = 'mailto:' + url;
i = match.index;
addText(raw.substr(0, i));
addLink(url, match[0].replace(MAILTO_REGEXP, ''));
raw = raw.substring(i + match[0].length);
}
addText(raw);
return html.join('');
function addText(text) {
if (!text) {
return;
}
html.push(text);
}
function addLink(url, text) {
html.push('<a ');
if (angular.isDefined(target)) {
html.push('target="');
html.push(target);
html.push('" ');
}
html.push('href="');
html.push(url);
html.push('">');
addText(text);
html.push('</a>');
}
};
}]);
答案 3 :(得分:1)
我想要一个交换文字的暂停按钮。我是这样做的:
CSS中的:
.playpause.paused .pause, .playpause .play { display:none; }
.playpause.paused .play { display:inline; }
模板中的:
<button class="playpause" ng-class="{paused:paused}" ng-click="paused = !paused">
<span class="play">play</span><span class="pause">pause</span>
</button>
答案 4 :(得分:0)
我会在指令的链接函数中分析文本:
directive("myDirective", function(){
return {
restrict: "A",
link: function(scope, element, attrs){
// use the 'element' to manipulate it's contents...
}
}
});
答案 5 :(得分:0)
受到@Neal的启发,我从新的Angular 1.5.8中做了这个“no sanitize”过滤器。它还识别没有ftp | http(s)的地址,但是以www开头。这意味着RedirectMatch 301 ^/(media-center)/\d+-(.+)$ /$1/$2
和https://google.com
都将被链接。
www.google.com