AngularJS에서 지시문을 동적으로 추가하려면 어떻게합니까?
나는 내가하고있는 일의 매우 삶은 버전을 가지고있어 문제가 발생합니다.
나는 간단하다 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 );
};
}
};
});
You'll notice I refactored your directive too in order to follow some best practices. Let me know if you have questions about any of those.
In addition to perfect Riceball LEE's example of adding a new element-directive
newElement = $compile("<div my-directive='n'></div>")($scope)
$element.parent().append(newElement)
Adding a new attribute-directive to existed element could be done using this way:
Let's say you wish to add on-the-fly my-directive
to the span
element.
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
Hope that helps.
Dynamically adding directives on angularjs has two styles:
Add an angularjs directive into another directive
- inserting a new element(directive)
- inserting a new attribute(directive) to element
inserting a new element(directive)
it's simple. And u can use in "link" or "compile".
var newElement = $compile( "<div my-diretive='n'></div>" )( $scope );
$element.parent().append( newElement );
inserting a new attribute to element
It's hard, and make me headache within two days.
Using "$compile" will raise critical recursive error!! Maybe it should ignore the current directive when re-compiling element.
$element.$set("myDirective", "expression");
var newElement = $compile( $element )( $scope ); // critical recursive error.
var newElement = angular.copy(element); // the same error too.
$element.replaceWith( newElement );
So, I have to find a way to call the directive "link" function. It's very hard to get the useful methods which are hidden deeply inside closures.
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)
Now, It's work well.
function addAttr(scope, el, attrName, attrValue) {
el.replaceWith($compile(el.clone().attr(attrName, attrValue))(scope));
}
The accepted answer by Josh David Miller works great if you are trying to dynamically add a directive that uses an inline template
. However if your directive takes advantage of templateUrl
his answer will not work. Here is what worked for me:
.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);
}
}
}
}]);
Josh David Miller is correct.
PCoelho, In case you're wondering what $compile
does behind the scenes and how HTML output is generated from the directive, please take a look below
The $compile
service compiles the fragment of HTML("< test text='n' >< / test >"
) that includes the directive("test" as an element) and produces a function. This function can then be executed with a scope to get the "HTML output from a directive".
var compileFunction = $compile("< test text='n' > < / test >");
var HtmlOutputFromDirective = compileFunction($scope);
More details with full code samples here: http://www.learn-angularjs-apps-projects.com/AngularJs/dynamically-add-directives-in-angularjs
Inspired from many of the previous answers I have came up with the following "stroman" directive that will replace itself with any other directives.
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
}
};
});
Important: Register the directives that you want to use with restrict: 'C'
. Like this:
app.directive('my-directive', function() {
return {
restrict: 'C',
template: 'Hi there',
};
});
You can use like this:
<stroman class="my-directive other-class" randomProperty="8"></stroman>
To get this:
<div class="my-directive other-class" randomProperty="8">Hi there</div>
Protip. If you don't want to use directives based on classes then you can change '<div></div>'
to something what you like. E.g. have a fixed attribute that contains the name of the desired directive instead of class
.
참고URL : https://stackoverflow.com/questions/15279244/how-can-i-dynamically-add-a-directive-in-angularjs
'Programing' 카테고리의 다른 글
Jest를 사용하여 ES6 모듈 가져 오기를 어떻게 조롱 할 수 있습니까? (0) | 2020.04.30 |
---|---|
MySQL : DISTINCT 값 발생 횟수 계산 (0) | 2020.04.30 |
두 목록을 연결- '+ ='와 extend ()의 차이점 (0) | 2020.04.30 |
AtomicInteger의 실제 사용 (0) | 2020.04.30 |
rmarkdown의 YAML 현재 날짜 (0) | 2020.04.30 |