I have a directive and a controller:
app.directive('responseBox', function(){
return {
restrict: 'E',
transclude: true,
templateUrl: 'responseBox.html',
link: function(scope, element, attrs) {
element.bind("click", function () {
scope.toggle();
})
}
}});
and a controller:
app.controller('responseBoxCtrl', function($scope) {
$scope.opened = false;
$scope.toggle = function() {
$scope.opened = !$scope.opened;
console.log($scope.opened);
}});
responseBox.html:
<div class="promptBlockResponse" ng-transclude>
<div class="btn-toolbar" style="text-align: right;">
<div class="btn-group" ng-show="opened">
<a class="btn btn-link" href="#"><i class="icon-pencil icon-white"></i></a>
<a class="btn btn-link" href="#"><i class="icon-remove icon-white"></i></a>
</div>
</div>
And in the main html file:
<response_box ng-controller="responseBoxCtrl"></response_box>
I want the btn-group to show when the opened variable is true. When I click the responseBox I can see the variable toggling, but the btn-group does not show/hide. What am I missing?
So repeating what Josh and I said in the comments above, the click handler runs "outside" of Angular, so you need to call scope.$apply()
to cause Angular to run a digest cycle to notice the change that was made to scope
(and then it will update your view):
$scope.toggle = function() {
$scope.opened = !$scope.opened;
console.log($scope.opened);
$scope.$apply();
}});
The link function can be eliminated by using ng-click in the template:
<div class="promptBlockResponse" ng-transclude ng-click="toggle()">
With Angular 1.3 and 1.2 the following snippet from an HTML template for a custom element directive:
<div ng-click="toggle($event)"></div>
<div ng-show="data.isOpen"></div>
And a snippet from the controller for that custom directive:
$scope.toggle = function ($event, destinationState) {
....
data.isOpen = true; //this is in scope and a digest cycle is already running
//calling $scope.$apply will cause an error
demonstrates an in scope scenario where you do need to use $apply.
I came across this SO question because I was using double brackets in my
<div ng-show="{{data.isOpen}}">
Changing to
<div ng-show="data.isOpen"></div>
got my binding working when I thought at first I had a scope issue.
So in angular 1.2 and 1.3 ng-click is not "outside" of Angular, at least using the signature I used for my toggle
function and is explained here:
$apply already in progress error
I discovered my double bracket ng-show issue that I initially thought was a scope issue thanks to this SO: why doesn't ng-show remove class ng-hide
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