角度:如何使用过滤器围绕文本字符串创建自定义链接

时间:2022-11-29 12:05:30

I am working with a json feed about cars. Part of the text has [VIN:'vin_number_is_here']Car make model here[/VIN]. I am using this in an ng-repeat and would like to, unless there's a better way, use a filter to process the text and create a hyperlink to a custom function ending up with something like <a ng-click="modalViewCar('vin_number_is_here')">Car make model here</a>

我正在处理一个关于汽车的json提要。部分文本中有[VIN:'vin_number_is_here']Car make model here[/VIN]。我在ng-repeat中使用它,除非有更好的方法,否则我希望使用一个过滤器来处理文本并创建一个到自定义函数的超链接,其结果如下所示:

I have the replacement of the [/VIN] done but am at a loss for how best to handle the opening "tag".**

我已经完成了[/VIN]的替换,但不知如何处理开头的“标签”。**

Additionally when I have hardcoded a test string I have found that the link never works which I assume is something Angular is responsible for...

另外,当我硬编码一个测试字符串时,我发现这个链接从来都不工作,我认为是角的原因。

app.filter('linkToVIN', ['$sce', function($sce) {
return function(input) {
    input = input.replace("[/VIN]","</a>");
    **input = input.replace("[VIN='12345abcdef']","<a ng-click=\"modalViewCar('12345abcdef')\">");**
    return $sce.trustAsHtml(input);
};

}]);

}));

<div ng-repeat="car in cars">
<div class="col-sm-12" ng-bind-html="car.details | filter:search | linkToVIN"></div>
</div>

The VIN link is in the body of text. Sometimes multiple times. So each ng-repeat has a {{car.details}} which may, about 1 in 3 times, have at least one string with the [VIN] structure. What I'd really like to do is hot link those as they appear within the text as so far I have found a few outlier cases where there are references to other [VIN] numbers. E.g.

VIN链接在文本正文中。有时很多次了。因此,每个ng-repeat都有一个{{car.details},它可能每3次就有一个带有[VIN]结构的字符串。我真正想做的是,将它们与文本中出现的内容联系起来,因为到目前为止,我发现了一些与其他[VIN]数字相关的异常情况。如。

Lorem ipsum dolor sit amet, [VIN:'12345abcdef']consectetur[/VIN] adipiscing elit. Vivamus laoreet odio nisi, eget gravida nunc porta gravida. Pellentesque nec porta tortor. In neque mi,[VIN:'000hijk']pretium[/VIN] at mattis ut, consectetur eget felis. Etiam tortor lacus, varius quis augue sed, condimentum varius massa.

Lorem ipsum dolor sit amet, [VIN:'12345abcdef']奉献了爱的elit。我要到那里去。Pellentesque nec门tortor。在neque mi,[VIN: 000hijk]pretium[/VIN]在mattis ut, resptetur eget felis。静脉曲张,静脉曲张,静脉曲张。

Which I would like to convert to.

我想把它转换成。

Lorem ipsum dolor sit amet, < a ng-click="modalViewCar('12345abcdef')" >consectetur< /a > adipiscing elit. Vivamus laoreet odio nisi, eget gravida nunc porta gravida. Pellentesque nec porta tortor. In neque mi,< a ng-click="modalViewCar('000hijk')" >pretium< /a > at mattis ut, consectetur eget felis. Etiam tortor lacus, varius quis augue sed, condimentum varius massa.

Lorem ipsum dolor sit amet, < a ng-click="modalViewCar('12345abcdef')"奉献我要到那里去。Pellentesque nec门tortor。在neque mi中,< a ng-click="modalViewCar('000hijk')"b0 pretium< /a >在mattis ut, resptetur eget felis。静脉曲张,静脉曲张,静脉曲张。

2 个解决方案

#1


1  

solving the regexp

You can do this with one regexp using multiple matching groups to build your anchor tags:

您可以使用一个regexp使用多个匹配组来构建锚标记:

data.replace(/\[VIN:'([\w\d-_]*)'\](.*?)\[\/VIN\]/gmi, '<a ng-click="vc.modalClick($1)">$2</a>')

test - https://regex101.com/r/tU5sG2/2

测试——https://regex101.com/r/tU5sG2/2

compiling the DOM

The next issue is that you need to compile the DOM correctly. In order to do that, I recommend a directive

下一个问题是您需要正确地编译DOM。为了做到这一点,我推荐一个指令

.directive('vinContainer', function($parse, $compile){
   restrict: 'A',
   link: function($scope, elem, attrs){
       regex = /\[VIN:'([\w\d-_]*)'\](.*?)\[\/VIN\]/gmi
       anchor = '<a href="#" ng-click="vc.modelClick(\'$1\')">$2</a>'

       data = $parse(attrs.ngModel)($scope)
       parsed = data.replace(regex, anchor)

       elem.html(parsed).show()
       $compile(elem.contents())($scope)
   }
}

usage

<div vin-container ng-model="vc.viewData"/>

codepen - http://codepen.io/jusopi/pen/VeebEO?editors=101

codepen——http://codepen.io/jusopi/pen/VeebEO?editors=101


This solution assumes that you are tightly coupling your directive to your view controller because your compiled anchors know which method to call. You could further break this down by:

这个解决方案假设您将指令与视图控制器紧密耦合,因为编译后的锚知道调用哪个方法。你可以通过:

  • creating an isolate scope with a callback expression you declare on the DOM
  • 使用在DOM上声明的回调表达式创建隔离范围
  • have the compiled links call the callback expression passing back the id as the payload
  • 编译后的链接是否调用回调表达式,将id作为有效负载返回

Doing it that way would be much more scalable. Here is the codepen for that version as well - http://codepen.io/jusopi/pen/yeeXJj?editors=101

那样做将会有更大的可扩展性。这是该版本的代码页——http://codepen.io/jusopi/pen/yeexj? editors=101

#2


0  

Say your cars array looks something like this

你的车阵看起来像这样。

var cars = [{details: "[VIN='12345abcdef']something[/VIN]"}, {details: ...}, ...];

You can transform it to a usable object by mapping the array

可以通过映射数组将其转换为可用对象

$scope.cars = cars.map(function(car) {
    var parts = car.details.match(/^\[VIN='(.+?)'\](.+?)\[\/VIN\]$/);
    return {
        vin: parts[1],
        details: parts[2]
    };
});

and then in your template

然后在模板中

<div ng-repeat="car in cars">
    <a ng-click="modalViewCar(car.vin)" ng-bind-html="car.details"></a>
</div>

This makes the assumption that all your car.details entries match the regular expression.

这使得假设所有的car.details条目都与正则表达式匹配。

#1


1  

solving the regexp

You can do this with one regexp using multiple matching groups to build your anchor tags:

您可以使用一个regexp使用多个匹配组来构建锚标记:

data.replace(/\[VIN:'([\w\d-_]*)'\](.*?)\[\/VIN\]/gmi, '<a ng-click="vc.modalClick($1)">$2</a>')

test - https://regex101.com/r/tU5sG2/2

测试——https://regex101.com/r/tU5sG2/2

compiling the DOM

The next issue is that you need to compile the DOM correctly. In order to do that, I recommend a directive

下一个问题是您需要正确地编译DOM。为了做到这一点,我推荐一个指令

.directive('vinContainer', function($parse, $compile){
   restrict: 'A',
   link: function($scope, elem, attrs){
       regex = /\[VIN:'([\w\d-_]*)'\](.*?)\[\/VIN\]/gmi
       anchor = '<a href="#" ng-click="vc.modelClick(\'$1\')">$2</a>'

       data = $parse(attrs.ngModel)($scope)
       parsed = data.replace(regex, anchor)

       elem.html(parsed).show()
       $compile(elem.contents())($scope)
   }
}

usage

<div vin-container ng-model="vc.viewData"/>

codepen - http://codepen.io/jusopi/pen/VeebEO?editors=101

codepen——http://codepen.io/jusopi/pen/VeebEO?editors=101


This solution assumes that you are tightly coupling your directive to your view controller because your compiled anchors know which method to call. You could further break this down by:

这个解决方案假设您将指令与视图控制器紧密耦合,因为编译后的锚知道调用哪个方法。你可以通过:

  • creating an isolate scope with a callback expression you declare on the DOM
  • 使用在DOM上声明的回调表达式创建隔离范围
  • have the compiled links call the callback expression passing back the id as the payload
  • 编译后的链接是否调用回调表达式,将id作为有效负载返回

Doing it that way would be much more scalable. Here is the codepen for that version as well - http://codepen.io/jusopi/pen/yeeXJj?editors=101

那样做将会有更大的可扩展性。这是该版本的代码页——http://codepen.io/jusopi/pen/yeexj? editors=101

#2


0  

Say your cars array looks something like this

你的车阵看起来像这样。

var cars = [{details: "[VIN='12345abcdef']something[/VIN]"}, {details: ...}, ...];

You can transform it to a usable object by mapping the array

可以通过映射数组将其转换为可用对象

$scope.cars = cars.map(function(car) {
    var parts = car.details.match(/^\[VIN='(.+?)'\](.+?)\[\/VIN\]$/);
    return {
        vin: parts[1],
        details: parts[2]
    };
});

and then in your template

然后在模板中

<div ng-repeat="car in cars">
    <a ng-click="modalViewCar(car.vin)" ng-bind-html="car.details"></a>
</div>

This makes the assumption that all your car.details entries match the regular expression.

这使得假设所有的car.details条目都与正则表达式匹配。