I'm trying to pass a variable from the current scope to a directive added via the $compile service.
I can pass a string to the child directive but not the actual object.
Here's a fiddle with the scenario : http://jsfiddle.net/ewx2trvx/2/
HTML:
<section ng-app="myApp" ng-controller="MainCtrl">
<addbuttonsbutton></addbuttonsbutton>
<div id="space-for-buttons"></div>
</section>
JS:
var myApp = angular.module('myApp', []);
function MainCtrl($scope) {
$scope.count = 0;
}
myApp.directive("addbuttonsbutton", function () {
return {
restrict: "E",
template: "<button addbuttons>Click to add buttons</button>"
}
});
//Directive for adding buttons on click that show an alert on click
myApp.directive("addbuttons", function ($compile) {
return function (scope, element, attrs) {
element.bind("click", function () {
scope.count++;
angular.element(document.getElementById('space-for-buttons'))
.append($compile("<alert alert='count'></alert>")(scope));
});
};
});
//Directive for showing an alert on click
myApp.directive("alert", function () {
return {
template: "<div><button class='btn btn-default'>Show alert # {{count}}</button></div>",
scope: {
a: '@alert'
},
replace:true,
link: function (scope, element, attrs) {
element.bind("click", function () {
console.log(scope.a);
alert("This is alert #" + scope.a);
});
}
};
});
Any thoughts?
Thanks.
Fir of all you need to apply scope after you compile and append because you are manipulating with DOM outside of the digest loop:
element.bind("click", function () {
scope.count++;
angular.element(document.getElementById('space-for-buttons'))
.append($compile("<alert alert='count'></alert>")(scope));
scope.$apply();
});
Then since you are using alert='count'
then you need to change scope configuration in alert
directive:
scope: {
a: '=alert'
},
Otherwise, if you use a: '@alert'
you need to interpolate it in the attribute like this: alert='{{count}}'
Finally, since the is two-way data binding, you can assign one more intermidiate primitive property to use as the index of the button:
myApp.directive("alert", function () {
return {
template: "<div><button class='btn btn-default'>Show alert # {{index}}</button></div>",
scope: {
a: '=alert'
},
replace:true,
link: function (scope, element, attrs) {
scope.index = scope.a;
element.bind("click", function () {
alert("This is alert #" + scope.index);
});
}
};
});
Demo: http://jsfiddle.net/ewx2trvx/3/
You need to interpolate the value to pass it otherwise angular assumes you want to have a string there.
Change your $compile("<alert alert='count'></alert>")(scope)
to $compile("<alert alert='{{count}}'></alert>")(scope)
and then convert the received string into a number: var count = +scope.a;
.
Additionally inside your template change {{count}}
to {{a}}
because you have an isolated scope here.
Note that in angular 1.2 there is no one-time-binding. If you use 1.3 you can one-time-bind with {{::count}}
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With