在AngularJS中dynamic添加指令

我有一个非常简化的版本,我正在做这个问题。

我有一个简单的directive 。 每当你点击一个元素,就会添加另一个元素。 但是,它需要先编译才能正确呈现。

我的研究导致我$compile 。 但是所有的例子都使用了一个复杂的结构,我不知道如何在这里应用。

小提琴在这里: http : //jsfiddle.net/paulocoelho/fBjbP/1/

而JS在这里:

 var module = angular.module('testApp', []) .directive('test', function () { return { restrict: 'E', template: '<p>{{text}}</p>', scope: { text: '@text' }, link:function(scope,element){ $( element ).click(function(){ // TODO: This does not do what it's supposed to :( $(this).parent().append("<test text='n'></test>"); }); } }; }); 

Josh David Miller解答: http : //jsfiddle.net/paulocoelho/fBjbP/2/

那里有很多毫无意义的jQuery,但是在这种情况下$ compile服务实际上是非常简单的

 .directive( 'test', function ( $compile ) { return { restrict: 'E', scope: { text: '@' }, template: '<p ng-click="add()">{{text}}</p>', controller: function ( $scope, $element ) { $scope.add = function () { var el = $compile( "<test text='n'></test>" )( $scope ); $element.parent().append( el ); }; } }; }); 

你会注意到我也重构了你的指令,以便遵循一些最佳实践。 如果您有任何疑问,请告诉我。

除了完美的Riceball LEE添加新元素指令的例子

 newElement = $compile("<div my-directive='n'></div>")($scope) $element.parent().append(newElement) 

添加一个新的属性指令到已存在的元素可以用这种方式完成:

假设您希望将实时my-directivespan元素。

 template: '<div>Hello <span>World</span></div>' link: ($scope, $element, $attrs) -> span = $element.find('span').clone() span.attr('my-directive', 'my-directive') span = $compile(span)($scope) $element.find('span').replaceWith span 

希望有所帮助。

在angularjs上dynamic添加指令有两种样式:

将angularjs指令添加到另一个指令中

  • 插入一个新的元素(指令)
  • 插入一个新的属性(指令)元素

插入一个新的元素(指令)

这很简单。 你可以使用“链接”或“编译”。

 var newElement = $compile( "<div my-diretive='n'></div>" )( $scope ); $element.parent().append( newElement ); 

插入一个新的属性元素

这很难,让我在两天之内头痛。

使用“$ compile”会引发严重的recursion错误! 也许在重新编译元素时应该忽略当前的指令。

 $element.$set("myDirective", "expression"); var newElement = $compile( $element )( $scope ); // critical recursive error. var newElement = angular.copy(element); // the same error too. $element.replaceWith( newElement ); 

所以,我必须find一种方法来调用指令“链接”function。 得到隐藏在封闭内的有用方法是非常困难的。

 compile: (tElement, tAttrs, transclude) -> links = [] myDirectiveLink = $injector.get('myDirective'+'Directive')[0] #this is the way links.push myDirectiveLink myAnotherDirectiveLink = ($scope, $element, attrs) -> #.... links.push myAnotherDirectiveLink return (scope, elm, attrs, ctrl) -> for link in links link(scope, elm, attrs, ctrl) 

现在,工作很好。

 function addAttr(scope, el, attrName, attrValue) { el.replaceWith($compile(el.clone().attr(attrName, attrValue))(scope)); } 

Josh David Miller接受的答案很好,如果你试图dynamic添加一个使用内联template的指令。 但是,如果您的指令利用templateUrl他的答案将无法正常工作。 这是什么对我有用:

 .directive('helperModal', [, "$compile", "$timeout", function ($compile, $timeout) { return { restrict: 'E', replace: true, scope: {}, templateUrl: "app/views/modal.html", link: function (scope, element, attrs) { scope.modalTitle = attrs.modaltitle; scope.modalContentDirective = attrs.modalcontentdirective; }, controller: function ($scope, $element, $attrs) { if ($attrs.modalcontentdirective != undefined && $attrs.modalcontentdirective != '') { var el = $compile($attrs.modalcontentdirective)($scope); $timeout(function () { $scope.$digest(); $element.find('.modal-body').append(el); }, 0); } } } }]); 

从许多以前的答案启发,我提出了以下“stroman”指令,将取代任何其他指令本身。

 app.directive('stroman', function($compile) { return { link: function(scope, el, attrName) { var newElem = angular.element('<div></div>'); // Copying all of the attributes for (let prop in attrName.$attr) { newElem.attr(prop, attrName[prop]); } el.replaceWith($compile(newElem)(scope)); // Replacing } }; }); 

重要提示:注册您想要使用的指令, restrict: 'C' 。 喜欢这个:

 app.directive('my-directive', function() { return { restrict: 'C', template: 'Hi there', }; }); 

你可以这样使用:

 <stroman class="my-directive other-class" randomProperty="8"></stroman> 

要得到这个:

 <div class="my-directive other-class" randomProperty="8">Hi there</div> 

普罗蒂普。 如果你不想使用基于类的指令,那么你可以把'<div></div>'改成你喜欢的东西。 例如有一个固定的属性,包含所需的指令而不是class

乔希大卫米勒是正确的。

PCoelho,如果你想知道后台的$compile是怎么做的,以及如何从指令生成HTML输出,请看下面

$compile服务编译包含指令(“test”作为一个元素)的HTML片段( "< test text='n' >< / test >" )并产生一个函数。 这个函数可以在一个范围内执行,以得到“来自指令的HTML输出”。

 var compileFunction = $compile("< test text='n' > < / test >"); var HtmlOutputFromDirective = compileFunction($scope); 

更多详细信息请参阅完整的代码示例: http : //www.learn-angularjs-apps-projects.com/AngularJs/dynamically-add-directives-in-angularjs