Mahesh Mahesh - 2 months ago 8
AngularJS Question

AngularJS dynamic custom directive issue

My custom directive runs fine onload page load but when added using append it does not run properly. It does not show its content when at in runtime.

HTML:

<!doctype html>
<html lang="en" ng-app="module1">
<head>
<meta charset="UTF-8">
<title>Angular Demo</title>

<link rel="stylesheet" href="css/bootstrap.css">

<script src="js/angular.js"></script>
<script src="js/ui-bootstrap-tpls-0.13.0.js"></script>
<script src="js/app.js"></script>
</head>
<body>

<div id="divContainer" style="border-style: solid;border-color:red;" ng-controller = "Controller1 as cnt1" >
<button ng-click="clicked();">Click Me!!</button>
<wlaccordion></wlaccordion>
</div>

</body>
</html>


app.js:

var app = angular.module('module1',[]);

app.controller('Controller1', ['$scope', function($scope) {

$scope.authorData = authorInfo;

$scope.clicked = function () {
alert('Clicked');
//angular.element(document.getElementById('divContainer')).append('<wlaccordion1></wlaccordion1>' (scope));
angular.element(document.getElementById('divContainer')).append('<wlaccordion></wlaccordion>');
}

}]);//controller1

var authorInfo = [
{
'name': 'Ray',
'rate': '10',
'show': 'true'
},
{
'name': 'Mahesh',
'rate': '12',
'show': 'true'
}
]

app.directive("wlaccordion", function($compile) {

var template = '<div ng-controller = "Controller1 as cnt1">' +
'<div ng-repeat="aData in authorData" ng-init="tab = 1">' +
'<ul>' +
'<li>' +
'<h1 ng-show={{aData.show}} ng-class="{active: tab === 1}"> {{aData.name}} </h1>' +
'<h1 ng-show={{aData.show}} ng-class="{active: tab === 2}"> {{aData.rate | currency}} </h1>' +
'</li>' +
'</ul>' +
'</div>' +
'</div>';

return{
link: function(scope, element){
var content = $compile(template)(scope);
element.append(content);
}
}
});


I would like the directive to function same as onload.

-Thanks
Mahesh

Answer

AngularJS intended for separation of presentation logic and business one. So I think you should do this in Angular way, your current approach is more jQuery one.

I would suggest you to add accordions collection to controller:

app.controller('Controller1', ['$scope', function($scope) {
    $scope.accordions = [0]; // Replace 0 with some actual data
    $scope.clicked = function() {
        $scope.accordions.push($scope.accordions.length); // Same here
    };
    // Your other code
}

And in HTML add ng-repeat:

<div id="divContainer" style="border-style: solid;border-color:red;" ng-controller = "Controller1 as cnt1" >
    <button ng-click="clicked();">Click Me!!</button> 
    <wlaccordion ng-repeat="accordion in accordions"></wlaccordion>
</div>  

Edit: Also don't forget to remove compilation from wlaccordion's link.

Edit #2: I suppose that authorInfo global var is used simply for example, however if it doesn't then consider usage of module.constant or module.value

Comments