我想知道我做的是否正确。
前言: 我开发了一个 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 实例)。
我的问题是:
- 我在这里做的很幼稚吗?
- 有一个更好的方法吗?
- 重新编译元素会导致性能问题吗?
- 以这种方式访问父范围会导致问题吗?
非常感谢您抽出宝贵时间:)