I want my ng-class to update when the variable in my controller changes. For some reason, it is only triggered on the page load and whilst the variable change, the ng-class does not update to reflect this.
Here is the code that triggers the variable change:
<a class="cs-mobile-menu__close-icon" ng-click="switchMobileMenu('right')">
</a>
Here is the code which I want to change depending on the variable:
<div class="right-menu__user"
ng-class="{
'animate': true,
'animate--leave': !isRightMenuOpen}">
{{user.firstName}} {{user.lastName}}
</div>
Here is the corresponding code from the controller:
$rootScope.isLeftMenuOpen = false;
$rootScope.isRightMenuOpen = false;
$scope.switchMobileMenu = function(direction) {
if (direction === 'left') {
$scope.isLeftMenuOpen = !($scope.isLeftMenuOpen);
} else {
$scope.isRightMenuOpen = !($scope.isRightMenuOpen);
}
};
It seems that ng-class is only set on the initial ng-click. I believe I need to wrap the above function in a $scope.apply() function so that the ng-class watches for changes and applies them as the ng-click toggles the variable. Am I on the right track? If so, how would I do this?
You don't need $scope.$apply. Working example: https://jsbin.com/fogasiniku/edit?html,js,output
Do you really have double dashes in the CSS class name?
Related
I tried the ng-class directive with a ternary and it works very well when the page load. My reference is the widthWindow.xs variable, it is "true" when the window size is a mobile, but there is a resize put it to "false" but the class does not change, the ng-class not dynamically changes. Why?
in the controller:
$scope.myResize = funcion(){
var number = $window.innerWidth;
if (number > 767) {
$scope.widthWindow.xs = false;
}else{
$scope.widthWindow.xs = true;
}
};
in the html:
<p ng-class="widthWindow.xs ? 'borderVoteNewsTop' : 'borderVoteNewsLeft'">Don't change when there is a resize</p>
Since the 'resize' event comes form outside the Angular framework, you need to integrate its actions with the AngularJS digest cycle. Use $apply.
$scope.myResize = function(){
var number = $window.innerWidth;
if (number > 767) {
$scope.$apply("widthWindow.xs = false");
}else{
$scope.$apply("widthWindow.xs = true");
}
};
After the $apply executes the Angular expression, it will automatically invoke a digest cycle and the watcher in the ng-class directive will see the change and update the class.
Your syntax for the ngClass directive is not correct.
Use it as following:
<p
ng-class="{'borderVoteNewsTop': widthWindow.xs, 'borderVoteNewsLeft': !widthWindow.xs}"
>
Change when there is a resize
</p>
Check out the directive documentation: https://docs.angularjs.org/api/ng/directive/ngClass
I have layout where I have:
<li ng-click="GetLoader();">ACCOUNT</li>
<li ng-click="GetLoader();">SETTINGS</li>
On the index page, I have a menu and ng-view where I can change pages on a click
Also included on the index page is a spinner.
<div class="loading" ng-show="ticketloading" ng-init="GetLoader()">
<div>
<img class="spinner" ng-src="~/Images/ajax-loader.gif" />
</div>
</div>
In my script I have -
$scope.GetLoader = function() {
$scope.ticketloading = true;
loader.css("z-index", "1");
}
My problem is that when a user clicks on "Account" it gets loaded, but just for few milliseconds. Then it changes to all blank. I receive data from ng-view. My question is how can I delay showing ng-view to show the loader a little bit longer.
Thanx in advance!
First of all you should avoid using DOM manipulations in controller. In your case it's better to use declarative ngClass directive to set opacity.
Then your actual issue is that you don't want to use static setTimeout to hide loaded, but rather listen $routeChangeSuccess:
$rootScope.$on('$routeChangeSuccess', function() {
$rootScope.ticketloading = false;
});
and use this loading flag in template like you are currently doing.
You can put above event listener in run block for example.
You can add property in your controller, for example dataLoading and add ng-if attribute to ng-view like this:
layout
<div ng-view ng-if="!dataLoading">
controller
function loadData()
{
var self = this;
self.dataLoading = true;
dataService.loadData(params, function(){
...
self.dataLoading = false;
});
}
In my project, thanks to animate.css, I can have entry animations like this:
<div class="row animated fadeInDown" ng-show="someCondition">
This is great. When someCondition is true, the div appears with an animation. What I don't understand is how to cause the reverse to happen. Say, in my controller I set someCondition = false;. What should I do in the markup to make the div do a fadeOutUp?
I tried putting the fade out in the class="" attribute, but that just conflicts with the fade in. I also tried ng-class={} but I don't know what condition is true when something is being removed.
Try a conditional ng-class:
<div ng-class="someCondition && 'fadeInDown' || 'fadeOutUp'">
UPDATE:
Use a variable class name in your markup:
<div ng-class="someClass">
and add a watch to the controller to apply the proper class name:
$scope.$watch('someCondition', function(newval, oldval){
if($scope.someCondition){
$scope.someClass = 'fadeInDown';
} else {
$scope.someClass = 'fadeOutUp';
}
});
In the following fiddle I added a setInterval to simulate the condition change:
http://jsfiddle.net/F52y5/59/
I'd like to set a default value to scope, which is picked up by ng-bind. I am doing this like:
<button>Show <span data-ng-bind="data.text" data-ng-init="data.text = 'All';"></span> Names</button>
In this example, the span is set to innerHTML = 'All' when the page loads.
However, I was hoping there might be a way to do this without requiring the use of ng-init, maybe something like:
<button>Show <span data-ng-bind="data.text = 'All';"></span> Names</button>
In your controller:
$scope.data = {};
$scope.data.text = "All";
Your markup:
<button>Show <span data-ng-bind="data.text"></span> Names</button>
Or, if you want to skip the controller code (courtesy of Kohjah Breese' comment):
<button>Show <span data-ng-bind="data.text || 'All'"></span> Names</button>
Presumably there will be some code elsewhere in your controller that will toggle this value, but for the purposes of initializing, that should do.
EDIT: Alternately, as tymeJV points out in the comments (ng-cloak added so {{}} syntax doesn't display to users):
<button>Show <span ng-cloak>{{data.text || "All"}}</span> Names</button>
The || operator works also in ngBind like in pure JavaScript:
<span ng-bind="myVariable || 'My default value'"></span>
This outputs myVariable if the variable is filled, otherwise the alternative 'My default value' is used.
from angularjs doc :
The only appropriate use of ngInit is for aliasing special properties of ngRepeat [...] Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
So i guess initializing data.text in your controller is fine for angularjs
Had this working earlier, now it doesnt respond accordingly.
In my html:
<div ng-click="setFalse();" ng-show"emptyspotslist">No results</div>
Controller:
$scope.setFalse = function () {
$scope.emptyspotslist = !$scope.emptyspotslist;
console.log($scope.emptyspotslist);
}
Default value of $scope.emptyspotslist = true.
The DIV doesnt hide, after clicking. Function gets called though.
Probably something really simple i'm overlooking.
You should have a = after ng-show attribute
Old
<div ng-click="setFalse();" ng-show"emptyspotslist">No results</div>
New
<div ng-click="setFalse();" ng-show="emptyspotslist">No results</div>
Your HTML is malformed...
ng-show="emptyspotslist"
You're missing an equals =.