在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-directive
到span
元素。
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