简体   繁体   English

如何将ng-bind-html行为封装到自定义指令中

[英]How to encapsulate ng-bind-html behavior into custom directive

I would like to abstract away ng-bind-html behavior from: 我想从以下内容中抽象出ng-bind-html行为:

<div ng-repeat="message in messages >
        <p ng-bind-html=message.title ng-phone-caller="message.title"> </p> 
    </div>

and move it into my custom directive which takes my string input and will wrap HTML tags around the phone numbers so that it's clickable on mobile. 并将其移动到我的自定义指令中,该指令接受我的字符串输入,并将HTML标签包裹在电话号码周围,以便可以在移动设备上点击。

    .directive('ngPhoneCaller',function() {
        return {
            scope: {
                ngPhoneCaller: '='
            },
            link: function (scope) {
var stringWithHtmlWrapper = $sce.getTrustedHtml(wrapStringWithPhoneNumberHTMLTag(scope.ngPhoneCaller));
                scope.ngPhoneCaller = $sce.trustAsHtml(stringWithHtmlWrapper);
            }
            }
        }
        });

so that anyone who uses my attribute directive ng-phone-caller doesn't need to also instantiate ng-bind-html. 这样,使用我的属性指令ng-phone-caller的任何人都不需要也实例化ng-bind-html。 Any suggestions as to how I would achieve this? 关于我将如何实现这一目标的任何建议? I tried utilizing $sce, but doesn't that still require me to use ng-bind-html? 我尝试使用$ sce,但这是否还不要求我使用ng-bind-html? For example, if I didn't use ng-bind-html with $sce, I ended up with an improperly formatted message ie) "We&# 8217;re currently unavailable. 例如,如果我不将ng-bind-html与$ sce一起使用,则最终得到的消息格式不正确,即:“我们当前不可用。

Have you considered using a filter for this? 您是否考虑过为此使用过滤器? Using $sce.trustAsHtml will allow your use of HTML as ng-bind-html does. 使用$sce.trustAsHtml将允许您像ng-bind-html一样使用HTML。

.filter('phoneCaller', function($sce) {
    return function(value) {
        return $sce.trustAsHtml(wrapStringWithPhoneNumberHTMLTag(value));
    };
});

You would use this filter as: 您可以将此过滤器用作:

<div ng-repeat="message in messages >
    <p ng-bind="message.title | phoneCaller"></p>
    <!-- Or alternately -->
    <p>{{ message.title | phoneCaller }}</p>
</div>

Update 更新

If you really don't want to use ng-bind-html in the client code, you can give your directive a simple template and create a function in a directive controller: 如果您确实不想在客户端代码中使用ng-bind-html ,则可以为您的指令提供一个简单的模板,并在指令控制器中创建一个函数:

angular.module('myapp').directive('ngPhoneCaller', function($sce) {
  return {
    restrict: 'A',
    scope: {
      ngPhoneCaller: '='
    },
    controller: function($scope) {
      $scope.wrappedPhoneCaller = function() {
        return $sce.trustAsHtml(wrapStringWithPhoneNumberHTMLTag($scope.ngPhoneCaller));
      }
    },
    template: '<p ng-bind-html="wrappedPhoneCaller()"></p>'
  };
});

Your client code would then look like: 您的客户端代码将如下所示:

<div ng-repeat="message in messages >
  <div ng-phone-caller="message.title"></div>
</div>

Since this is calculating it on every digest cycle, you might look to cache it or set up your own $watch in the controller to bind to this as a normal $scope property (not a functional call). 由于此操作是在每个摘要周期中计算的,因此您可能希望对其进行缓存或在控制器中设置自己的$watch ,以将其绑定为常规的$ scope属性(而不是功能调用)。

Use $sce : 使用$sce

.directive('ngPhoneCaller',function($sce) {
    return {
        scope: {
            ngPhoneCaller: '='
        },
        link: function (scope, element) {
            var html = wrapStringWithPhoneNumberHTMLTag(scope.ngPhoneCaller);
            element.html($sce.getTrustedHtml(html) || '');
        }
    }
    });

You also need to add $watch to affect any scope changes. 您还需要添加$watch以影响任何范围更改。

For more info about, you can read original ngBindHtml implementation . 有关更多信息,您可以阅读原始的ngBindHtml 实现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM