Jorge A. Jorge A. - 6 months ago 17
AngularJS Question

Modifying styles of a compiled html element in Angularjs

UPDATE

I think I found the issue, the template variable is lossing it's value, I don't get why yet, I've changed the code a bit:

var template;

$templateRequest("ng-templates/app/cart-counter.html").then(function(html){
template = angular.element(html);
element.append(template);
$compile(template)(scope);
console.log("template: " + template); // This returns the template object
});

var unbindWatcher = scope.$watch(
"clickCounter",
function(newClickCounter){
console.log("template: " + template); // This returns undefined
if (newClickCounter >= 5) {
var cartButton = this.template.children('.btn');

cartButton.toggleClass('btn-success'); // this throws undefined error

unbindWatcher();
}
}
);


My question now would be why is the template variable undefined when it had a value earlier and what should I do to fix it?

ORIGINAL QUESTION

I am playing around with Angular, trying to change some elements classes by compiling an html adding it to the DOM and when an event happens, I am trying to use angularElement to access the childs of the html I compiled and toggling some classes.

This is not giving me an error, but the changes in the classes are not happening and I can't find what Im doing wrong, please help.

This is the code for the directive:

store.directive("appCartCounter", ['$templateRequest', '$compile', function($templateRequest, $compile){
var link = function(scope, element){
this.messages = [
"Sorry, the shopping cart is not implemented",
"Hey, I told you, it's not ready",
"Stop that! It's anoying",
"I'm getting really really angry",
"YEarghhh!!!!"
];

scope.messages = this.messsages;
scope.clickCounter = 0;
scope.incrementCount = function(){
scope.clickCounter++;
};

$templateRequest("ng-templates/app/cart-counter.html").then(function(html){
this.template = angular.element(html);
element.append(template);
$compile(template)(scope);
});

var unbindWatcher = scope.$watch(
"clickCounter",
function(newClickCounter){
console.log("I've been watching you... alalalong");
if (newClickCounter >= 5) {
var cartButton = this.template.children('.btn');
var messageElement = this.template.children('.text-info');
cartButton.toggleClass('btn-success');
cartButton.toggleClass('btn-danger');
cartButton.toggleClass('btn-lg');

messageElement.toggleClass('text-info');
messageElement.toggleClass('text-danger');
messageElement.toggleClass('text-capitalize');
messageElement.toggleClass('lead');

unbindWatcher();
console.log("I'm blind!!");
}
}
);

};

return {
restrict: 'E',
scope: {
'addedProducts' : '='
},
replace: 'true',
link: link
};
}]);


cart-counter.html:

<button
class="btn btn-success"
data-ng-show="addedProducts.length"
data-ng-click="incrementCount()"
data-ng-cloak>
<i class="glyphicon glyphicon-shopping-cart"></i> {{addedProducts.length}}
</button>
<p data-ng-show="clickCounter" class="text-info">
{{messages[clickCounter]}}
</p>


html using the directive:

<app-cart-counter data-added-products="storeCtrl.addedProducts"></app-cart-counter>


I'll try to get a simpler example in a plunker.

Thanks!!

Answer

In the end I managed to "fix" the problem by saving the template to the scope, altough I still don't understand why the variable or the saving it to "this." didn't worked.

As a sidenote, selecting the children via tagname didn't worked, I also tried with the children number and classname (even though I have jquery imported in the solution). To solve that, I had to access the elements via the template object's array, and wrap that in an angular.element(), eg:

var cartButton = angular.element(scope.template[0]);
var messageElement = angular.element(scope.template[2]);

PS: scope.template[1] returned me a text node because of the linebreak, I hadn't expected that.

Comments