1

我想知道我做的是否正确。

前言: 我开发了一个 Typeahead 类,它消耗资源并将结果存储在自身中。该类或多或少具有以下结构:

  • 输入:存储搜索文本的位置。
  • 列表:存储结果的位置。
  • change:每次输入更改时执行的函数。
  • cursor:跟踪当前悬停/选定元素的函数。

问题是,如果我想将所有必需的属性附加到输入,代码看起来很臃肿:

<input 
  type="text"
  ng-model="myTa.input"
  ng-change="myTa.change();"
  ng-keyup="myTa.cursor()"
  .... 
/>

我想要完成的是一个只需要 Typeahead 实例的指令,它会自动将所有必需的属性附加到元素。例如:

<input type="text" my-typeahead="myTa" />

在继续之前,我想明确以下几点:

  • 我不想使用模板,也不想使用 templateUrl,因为我想让指令非常灵活,让它附加到输入、文本区域、选择甚至链接。
  • 我不想使用 attrs.$observe 或 scope.$watch ,因为 ng-model 做得很好并且完成了我正在寻找的东西。
  • 我知道根元素中的新元素无需任何技巧即可编译,但父元素本身不会编译新指令。(这是有道理的)

现在,如果我这样做,我会在地狱中燃烧吗:

angular
.module('myTypeaheadDirective', [])
.directive('myTypeahead', function($compile, $rootScope) {
    return {
        restrict: 'A',
        scope: {
            typeahead: '=myTypeahead'
        },
        compile: function() {
            return {
                pre: function precompile(scope, element, attrs) {
                    var installedAttribute = 'my-typeahead-installed';

                    if ( angular.isUndefined( element.attr( installedAttribute ) ) ) {
                        element.attr('ng-model', 'typeahead.input');
                        element.attr('ng-change', 'typeahead.change()');
                        element.attr( installedAttribute, true );
                        $compile(element)(scope.$parent);
                    }
                }
            }
        }
    }
});

解释代码:

指令预编译过程会检查是否已经安装,否则会进入死循环。

在条件中,我根据需要添加尽可能多的指令。

请注意,我使用的是 ng-model="typeahead.input" 但这是一个隔离的范围,因此我可以有多个输入具有不同的 typeahead 实例。

附加新指令后,我使用 $compile 服务使用父作用域重新编译元素(因此它可以访问原始 typeahead 实例)。

我的问题是:

  • 我在这里做的很幼稚吗?
  • 有一个更好的方法吗?
  • 重新编译元素会导致性能问题吗?
  • 以这种方式访问​​父范围会导致问题吗?

非常感谢您抽出宝贵时间:)

4

1 回答 1

0

由于您传递到隔离范围的内容可以很容易地从属性值中使用......可以删除隔离范围,然后指令范围将是父范围。

要从属性设置 typeahead 对象只能:

var typeahead= attrs.myTypeahead;
element.attr('ng-model', typeahead+'.input');
于 2013-11-07T04:40:40.227 回答