I'm having some problems with a directive that I want to be dynamically added as the user clicks a button. What would be the best approach to achieve this?
In my research I've found element.bind
(from jqLite), but I haven't found lots of examples on the internet.
Here's my code:
<div class="form-group"> <button class="btn btn-info" ng-click="addAttr()">Add Atributtes</button> </div> <addattributes options="attributes" attr="obj"></addattributes>
.directive('addattributes', function () { return { restrict: 'E', scope: { attributes: '=options', attr: '=' }, template: '<div ng-class="classInput">' + ' <div class="col-md-8" style="padding-left: 0;">' + ' <label>Nome do Atributo</label>' + ' <input type="text" class="form-control" placeholder="Attrs name" ng-model="attrname" ng-change="validation()">' + ' </div>' + ' <div class="col-md-4" style="padding-right: 0;"> ' + ' <label>Tipo do Atributo</label> ' + ' <select class="form-control" ng-options="attribute.name for attribute in attributes" ng-model="attrtype"></select>' + ' </div> '+ ' <div class="clearfix"> '+ ' <div> '+ ' <button type="button" class="btn btn-default btn-xs pull-right" ng-click="changeButton()" style="margin-top: 1em;" ng-show="showBtn == true"> Adicionar </button> ' + ' </div> {{attr}}'+ '</div>', link: function(scope,element,attrs){ scope.showBtn = true; scope.classInput = 'form-group'; scope.attrtype= scope.attributes[2]; scope.changeButton = function(){ scope.showBtn = false; scope.attr = { name: scope.attrname, type: scope.attrtype }; } scope.validation = function(){ if(scope.attrname.length < 6) { scope.classInput = 'form-group has-error'; } else { scope.classInput = 'form-group has-success'; } } } };})
Thanks in advance, have a great day!
You don't "add a directive" in the controller. This means that you are manipulating DOM, which you should not do.
Instead, think in terms of ViewModel. What ViewModel property does this directive display/alter? Say it is an "attribute", so add an attribute
to $scope.myAttributes
(to avoid name collision with some attributes
property that you have) array.
$scope.myAttributes = [];
$scope.addAttr = function(){
$scope.myAttributes.push({}); // empty object to hold some property of an "attribute"
}
Then, in the View, ng-repeat
over attributes
:
<div class="form-group">
<button class="btn btn-info" ng-click="addAttr()">Add Atributtes</button>
</div>
<addattributes ng-repeat="attribute in myAttributes" attr="attribute"></addattributes>
(I'm not fully understanding what your addattributes
directive does, so I'm assuming that it sets an attribute object via attr
)
Without giving some details of your use-case, it's hard to tell whether what you're trying to achieve could be more simply (and importantly more intuitively) done with ng-show
, ng-switch
or some other ng-
directive, but we'll assume that your approach is well thought through.
As @New Dev has already pointed out in another answer, you should try to keep DOM manipulation inside a directive, and NOT in a controller - this will help with testability, separation of concerns, and many, many other things.
The below code demonstrates how to do what you're trying to do, but in an abstract way, because your example looks too complex for a simple answer.
If your directive is an element called newDirective
adding it is a three step process:
You should do this in the link function of a directive where you have access to the element:
link: function (scope, element, attributes) {
scope.addDirective = function () {
// create the new directive element
$newDirective = angular.element('<new-directive>');
// Append it to the DOM
element.append($newDirective);
// compile it and link it to the scope
$compile($newDirective)(scope);
}
}
Note that a directive's compile
function returns its link function, so the compile & link is actually two steps in one line.
See the runnable code snippet below. myDirective
adds newDirective
s. The newDirective
's template contains a button that removes it. Clicking the remove button works, proving the link function has been run and the directive is functioning properly.
angular.module('app', []) .directive('myDirective', function ( $compile ){ return { restrict: 'E', template: '<button ng-click="addDirective()">Click me!</button>', link: function (scope, element, attributes) { scope.addDirective = function () { // create the new directive element $newDirective = angular.element('<new-directive>'); // Append it to the DOM element.append($newDirective); // compile it and link it to the scope $compile( $newDirective )(scope); } } } }) .directive('newDirective', function ( $compile ){ return { restrict: 'E', template: '<li>{{someText}}' + '<button ng-click="remove()">Remove</button>' + '</li>', link: function (scope, element, attributes) { scope.someText = "If the scope is linked this will show"; scope.remove = function () { element.remove() } } } });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"> </script> <div ng-app="app"> <my-directive></my-directive> </div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.