Javascript 重新编译Angle指令以编程方式添加ng模块和ng更改

Javascript 重新编译Angle指令以编程方式添加ng模块和ng更改,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我想知道我是否做得对 序言: 我开发了一个Typeahead类,它使用一个资源并将结果存储在自己内部。该类或多或少具有以下结构: 输入:存储搜索文本的位置 列表:存储结果的位置 更改:每次输入更改时执行的函数 光标:跟踪当前悬停/选定元素的函数 问题是,如果我想将所有必需的属性附加到输入,代码看起来过于臃肿: <input type="text" ng-model="myTa.input" ng-change="myTa.change();" ng-keyup="my

我想知道我是否做得对

序言: 我开发了一个Typeahead类,它使用一个资源并将结果存储在自己内部。该类或多或少具有以下结构:

  • 输入:存储搜索文本的位置
  • 列表:存储结果的位置
  • 更改:每次输入更改时执行的函数
  • 光标:跟踪当前悬停/选定元素的函数
问题是,如果我想将所有必需的属性附加到输入,代码看起来过于臃肿:

<input 
  type="text"
  ng-model="myTa.input"
  ng-change="myTa.change();"
  ng-keyup="myTa.cursor()"
  .... 
/>
解释代码:

指令预编译过程检查它是否已经安装,否则它将进入无限循环

在条件中,我添加了我想要的任意多个指令

请注意,我使用的是ng model=“typeahead.input”,但这是一个独立的范围,因此我可以使用不同的typeahead实例获得多个输入

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

我的问题是:

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

非常感谢您花时间:)

因为您传递到隔离作用域的内容可以很容易地从属性值中使用…可以删除隔离作用域,然后指令作用域将是父级的

要仅从属性设置typeahead对象,可以执行以下操作:

var typeahead= attrs.myTypeahead;
element.attr('ng-model', typeahead+'.input');

我也尝试过这种方法,但不起作用。主要原因是angular不注意编译过程后添加到元素中的任何ng模型、ng更改等。为了解决这个问题,我像您一样添加了ng模型attr,然后使用$compile(element,scope)重新编译元素。我不需要使用typeahead+'.input',只需要使用“typeahead.input”,因为编译后它会查看自己的作用域。我刚才做的另一件事是使用scope.typeahead=scope.$eval(attrs.myTypeahead)。通过这种方式,人们可以传递一个typeahead实例或一个最终将返回一个实例的函数。很好的把戏,虽然我仍然怀疑我是否做错了什么(尽管它有效)
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);
                    }
                }
            }
        }
    }
});
var typeahead= attrs.myTypeahead;
element.attr('ng-model', typeahead+'.input');