使用类似于jQuery的插件扩展AngularJS

3
我正在创建一个AngularJS指令,用于绑定控制器作用域上包含'html'字符串的属性。该字符串从后端数据库中获取。我希望将HTML追加到包含指令属性的元素中。之后,我想深入新创建的元素并使用span包围每个“单词”。我使用类似于jQuery高亮插件的jQuery扩展函数实现了后者。实际上,我的代码是此插件的原始代码修改版:
jQuery.extend({
highlight: function (node, re) {
    if (node.nodeType === 3) {
        var match = node.data.match(re);
        if (match) {
            var highlight = document.createElement('span');               
            highlight.className = 'highlight';
            var wordNode = node.splitText(match.index);
            wordNode.splitText(match[0].length);
            var wordClone = wordNode.cloneNode(true);
            highlight.appendChild(wordClone);             
            wordNode.parentNode.replaceChild(highlight, wordNode);
            return 1; //skip added node in parent
        }
    } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
            !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
            !(node.tagName === 'SPAN' && node.hasAttribute('ng-class'))) { // skip if already highlighted
        for (var i = 0; i < node.childNodes.length; i++) {
            i += jQuery.highlight(node.childNodes[i], re);
        }
    }
    return 0;
}
});

jQuery.fn.highlight = function (times) {
  var pattern = "\\b([^ ]+)\\b";
  var re = new RegExp(pattern);
  return this.each(function () {
    jQuery.highlight(this, re);
 });
};

我的指令代码:

.directive('spanner', function($compile){
var linkFn = function(scope, element)
{
   element.append(scope.spanner);
   element.highlight();
   $compile(element.contents())(scope);
};

return {
    scope: {
        spanner: '='
    },
    restrict: 'A',
    link: linkFn
  };  
});

这段代码可以正常工作,但是我使用的是jQuery。我更希望扩展AngularJs提供的jQlite(或者以某种方式无需扩展!)。我尝试扩展jQlite,但每次都失败了。有人能建议一种不依赖于jQuery就能实现的方法吗?我认为这将大大提高我的AngularJs理解水平。先感谢您。

1个回答

1

由于插件的90%是原生脚本,因此将其移植为指令非常简单且不依赖任何库(jQuery或jQlite):

app.directive('highlight', function() {
  /* define highligher variables and function */
  var pattern = "\\b([^ ]+)\\b";
  var re = new RegExp(pattern);

  var highlighter = function(node, re) {
    if (node.nodeType === 3) {
      var match = node.data.match(re);
      if (match) {
        var highlight = document.createElement('span');
        highlight.className = 'highlight';
        var wordNode = node.splitText(match.index);
        wordNode.splitText(match[0].length);
        var wordClone = wordNode.cloneNode(true);
        highlight.appendChild(wordClone);
        wordNode.parentNode.replaceChild(highlight, wordNode);
        return 1; //skip added node in parent
      }
    } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
      !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
      !(node.tagName === 'SPAN' && node.hasAttribute('ng-class'))) { // skip if already highlighted
      for (var i = 0; i < node.childNodes.length; i++) {
        i += highlighter(node.childNodes[i], re);
      }
    }
    return 0;
  }

   /* return directive link function */    
   return function(scope, elem) {
      /* initalize on element */
      highlighter(elem[0], re);
    }    

});

HTML
 <p highlight>Far far away</p>

演示

(将英文单词“DEMO”翻译成了中文单词“演示”)

谢谢!这太惊人了!它真正验证了Angular的DOM操作方式!我非常感激!愿上帝保佑! - rmg.n3t
甚至可以将函数放入工厂中,这样就不必为每个元素声明它...然后只需注入该工厂即可。 - charlietfl
那绝对是一种高效的方法。再次感谢! - rmg.n3t

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接