AngularJS $scope variable does not go into view - javascript

I have a simple boolean variable that switches a DIV to be hidden at startup and then shown after an action until the end of the application. But it does not switch - the DIV is always hidden. Please help, what is wrong in the code below:
<div class="right" ng-controller="EmployeeDetailsCtrl" ng-show={{showEmployeeDetails}}>
<p>{{employee.name}} {{employee.surname}}</p>
</div>
inside EmployeeDetailsCtrl controller:
$scope.$on('showEmployee', function (event, data) {
$scope.showEmployeeDetails = true;
$scope.employee = data;
});
$scope.showEmployeeDetails = false;
BTW, the $scope.employee variable updates correctly after the event is triggered, so I'm really stuck what's going on here.

Remove the {{}} from your ng-show, like so:
<div class="right" ng-controller="EmployeeDetailsCtrl" ng-show="showEmployeeDetails">
<p>{{employee.name}} {{employee.surname}}</p>
</div>

When you're using ng-show you're binding to an expression, not a string, so just use:
ng-show="showEmployeeDetails". That's why you can do more complex stuff like ng-show="1 + 1 === 2".
If that still doesn't cut it, it could be a scoping issue with primitives being assigned to a child scope and not seen up the parent scope. It doesn't look like it from the code you showed but perhaps it's simplified for this question, you never know.

Related

Why $scope.getList() gets invoked on state change of $scope.showList?

In the below code,
<label>
<input type="checkbox" ng-model="showList">
Show unordered list
</label>
<ng-include src="getList()"></ng-include>
$scope.getList() gets invoked on change of $scope.showList by check or uncheck, where $scope.showList is used as,
app3.controller('gListCtrl', function($scope){
$scope.getList = function(){
return $scope.showList ? "ulgrocerylist.html" : "grocerylist.html";
};
});
Why $scope.getList() gets invoked on change of state of $scope.showList?
Similar code,
<p>
<button ng-disabled="disableButton">Button</button>
</p>
<p>
<input type="checkbox"
ng-model="disableButton">DisableButton
</p>
make sense to me, because disableButton state is changing, so button gets disabled or enabled due to two way binding.
First of all, You're a little bit incorrect on your question. The $scope.getList() function gets invoked not only on a state change, but on every digest cycle. Let me explain.
Because the framework has absolutelly no clue what code is in the getList function. It does not statically analize your code, since it would be both very hard and very inneficient. Due to the nature of how you can use AngularJS, you could be changing the output of getList according to a variable in a completely different controller, service, scope, etc. Thus, this output might need to be rerendered upon every digest cycle. AngularJS recognizes this, because you have the function call in your template and calls it on every digest to check whether it needs to swap out the template.
Consider this application structure:
<div ng-app="testTest">
<script type="text/ng-template" id="template.html">
<div>Hello world!</div>
</script>
<div ng-controller="templateViewer">
<div>
<div ng-include="content()"></div>
</div>
</div>
<div ng-controller="templateChanger">
<button ng-click="handleClick()">Show / hide content</button>
</div>
</div>
and this code to wire it:
var app = angular.module('testTest', []);
app.factory('template', function() {
return {
show: false
};
});
app.controller('templateChanger', function($scope, template) {
$scope.handleClick = function() {
// toggle showing of template
template.show = !template.show;
};
});
app.controller('templateViewer', function($scope, template) {
// if the result of this function is not re-evaluated on every digest cycle,
// Angular has no idea whether to show or hide the template.
$scope.content = function() {
return template.show ? 'template.html' : '';
};
});
So, the framework needs to rely on this constant re-evaluation of properties and functions that are binded to the templates in the HTML. Since all the data structures that you use are plain javascript objects, and you don't explicitly tell the framework that something in your viewmodel has changed (as you would do by invoking set() methods on your models in other frameworks, such as Backbone or Ember) – angular has to check all variables and re-run all the functions that could possibly change the look of your view, and ng-include is one of these cases.
You can use watcher or observe events on showList variable value changes.

AngularJS: Ng-click passes parameter into correct Ng-show

I have an app with several modals on the page. What I'd like to do is have only one controller function that toggles the visibility of the modals. So, let's say I have the following:
<a href ng-click="openModal(modal1)></a>
<a href ng-click="openModal(modal2)></a>
Then I'd like the modals to have something along the lines of:
<div class="modal" ng-show="openModal(modal1)">
<div class="modal" ng-show="openModal(modal2)">
Hope this is clear. I'm new to angular so kind of lost on this one. I know I can set a bunch of functions that toggle the boolean of that specific modal type, but then my controller would get big pretty fast. I'd like to keep it as concise and clean as possible. Thank you in advance for your time.
angular.module('ngToggle', [])
.controller('AppCtrl',['$scope', function($scope){
$scope.custom = true;
$scope.toggleCustom = function() {
$scope.custom = $scope.custom === false ? true: false;
};
}]);
Use ng-toggle and do an ng-toggle. It works on-click and you'll just need to set the property for each modal and then pass it in. So, something like..
$scope.modal1visibility = true;
$scope.modal2visibility = false;
Then you should just be able to pass in those individual properties to the toggle functions and that should do what you're wanting it to do. Hope I understood your question and that this helps
http://www.bennadel.com/blog/2806-creating-a-simple-modal-system-in-angularjs.htm this link looks like it might be what you're talking about. I think I may have misunderstood after some further looking..

Angular ng-show doesn't work properly when value changes

I'm trying to show div depends on permission of log in user.
<div class="container">
<p> {{permission}}</p>
<div ng-show="permission" class="admin_panel">
....
</div>
</div>
and in controller, it is set:
$scope.init = function(){
if($window.sessionStorage.isAdmin){
$scope.permission = $window.sessionStorage.isAdmin;
}
$log.info("are you admin??? " + $scope.permission);
};
$scope.init();
In console, I could verify that permission was set to false and {{permission}} also showed
its value is false. However, ng-show is still showing even though the value is false. I'm not sure what's wrong with this.
Have you tried ng-show="permission === true;"? ng-show, to my understanding, is meant to evaluate whatever is inside the quotes. this would just explicitly state the evaluation. I've had experiences where just having a variable inside the quotes isn't an evaluation that ng-show recognizes for some odd reason.
I had a similar problem except that my variable was changed inside
a timeout function like this:
<div ng-show="check"> something .... </div>
setTimeout(function(){
check = false;
},500);
the problem was solved when i added $scope.$apply() inside timeout:
setTimeout(function(){
check = false;
$scope.$apply()
},500);
If you want to show or hide some content that depends of the user permissions, instead of using "ng-show", you should use "ng-if".
ng-show/ng-hide only adds or remove a CSS class that show or hide that element (display:none), but an user could change it easily in the browser.
Using ng-if: "If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM."
https://docs.angularjs.org/api/ng/directive/ngIf
I have a same problem and every thing work fine except ng-show. I missed something stupid. when you call a controller from different part of your document you can not share data between them. for example i have 2 div tag
in document
<div id="1" ng-controller="contentCtrl">
<div ng-click="toggleSidebarShow()">
<!-- some code here -->
</div>
</div>
<div id="2" ng-controller="contentCtrl">
<div ng-show="showSidebar">
</div>
</div>
showSidebar between contentCtrl of div 1 and div2 wasn't share.
in controller
// some code
$scope.showSidebar = true;
$scope.toggleSidebar = function (){
$scope.showSidebar = ! $scope.showSidebar;
};
but this code doesn't work because toggleSidebar called outside of the div2 tag and have it's own showSidebar. To conquer this problem you had to use service or modules. see this link to more information.
One more thing to check is when your page loads, in the inspect element check if the element you are trying to use ng-show on is rendered inside the element which has the ng-controller directive.
If your element with ng-show is outside the ng-controller element then ng-show wont work

get the text of div using angularjs

i want to get the text of div using angularjs . I have this code
<div ng-click="update()" id="myform.value">Here </div>
where as my controller is something like this
var myapp= angular.module("myapp",[]);
myapp.controller("HelloController",function($scope,$http){
$scope.myform ={};
function update()
{
// If i have a textbox i can get its value from below alert
alert($scope.myform.value);
}
});
Can anyone also recommand me any good link for angularjs . I dont find angularjs reference as a learning source .
You should send the click event in the function, your html code should be :
<div ng-click="update($event)" id="myform.value">Here </div>
And your update function should have the event parameter which you'll get the div element from and then get the text from the element like this :
function update(event)
{
alert(event.target.innerHTML);
}
i just thought i put together a proper answer for everybody looking into this question later.
Whenever you do have the desire to change dom elements in angular you need to make a step back and think once more what exactly you want to achieve. Chances are you are doing something wring (unless you are in a link function there you should handle exactly that).
So where is the value comming, it should not come from the dom itself, it should be within your controller and brought into the dom with a ng-bind or {{ }} expression like:
<div>{{ likeText }}</div>
In the controller now you can change the text as needed by doing:
$scope.likeText = 'Like';
$scope.update = function() {
$scope.likeText = 'dislike';
}
For angular tutorials there is a good resource here -> http://angular.codeschool.com/
Redefine your function as
$scope.update = function() {
alert($scope.myform.value);
}
A better way to do it would be to use ng-model
https://docs.angularjs.org/api/ng/directive/ngModel
Check the example, these docs can be a bit wordy

ng-click not firing in AngularJS while onclick does

I am trying to use AngularJS in my application and have been successful to some extent.
I am able to fetch data and display it to the user. And I have a button in ng-repeat via which I want to post DELETE request. Below is my code which does it.
<div class="navbar-collapse collapse">
<table class="table table-striped" ng-controller="FetchViewData">
<tr>
<td>Name</td>
<td>ID</td>
<td>Department</td>
<td></td>
</tr>
<tr ng-repeat="d in viewData">
<td>{{d.EmployeeName}}</td>
<td>{{d.EmployeeID}}</td>
<td>{{d.EmployeeDepartment}}</td>
<td>
<button class="trashButton" type="button"
name="view:_id1:_id2:_id14:_id24:btnDelete"
id="view:_id1:_id2:_id14:_id24:btnDelete"
ng-click="deleteRecord('{{d['#link'].href}}')">
<img src="/trashicon.gif"></button>
</td>
</tr>
</table>
</div>
This is the FetchViewData function which fetches the information and displays it to the user.
function FetchViewData($scope, $http) {
var test_link = "<MY LINK>";
$http.get(test_link).success( function(data) {
$scope.viewData = data;
});
}
The data is fetched and properly displayed.
But the code in ng-click="deleteRecord('{{d['#link'].href}}')" does not fire when delete button is clicked. In Google Chrome's developer tools I can see valid values are generated for code {{d['#link'].href}} but the code deleteRecord does not get fired. From this question I tried removing the braces and writing only d['#link'].href but it didn't work for me.
When I replace ng-click with onclick the deleteRecord function gets fired.
function deleteRecord(docURL) {
console.log(docURL);
$http.delete(docURL);
}
But then I receive the below error.
Uncaught ReferenceError: $http is not defined
deleteRecord
onclick
I am using jQuery 1.10.2 and AngularJS v1.0.8.
FetchViewData here is a controller, and in your html, where you have ng-controller="FetchViewData", you are telling it to look within that controller's scope for any angular methods and variables.
That means, if you want to call a method on click, it needs to be calling something attached to your controller's scope.
function FetchViewData($scope, $http) {
var test_link = "<MY LINK>";
$http.get(test_link).success( function(data) {
$scope.viewData = data;
});
$scope.deleteRecord = function(docURL) {
console.log(docURL);
$http.delete(docURL);
}
}
Here, the function exists on the scope, and any html that is inside your FetchViewData Controller has access to that scope, and you should be able to call your methods.
It's working when you use on-click because your function exists in the global namespace, which is where on-click is going to look. Angular is very heavily reliant on scoping to keep your namespaces clean, there's lots of info here: https://github.com/angular/angular.js/wiki/Understanding-Scopes
INSTEAD of this
ng-click="deleteRecord('{{d['#link'].href}}')"
TRY this
ng-click="deleteRecord(d['#link'].href)"
You don't need to use curly brackets ({{}}) in the ng-click
ENJOY...
function deleteRecord(docURL) {
console.log(docURL);
$http.delete(docURL);
}
It should be
$scope.deleteRecord = function (docURL) {
console.log(docURL);
$http.delete(docURL);
}
EDIT:
change something in html and controller ....
SEE WORKING DEMO
The deleteRecord method should be assigned in the current and correct scope
$scope.deleteRecord = function(){
....
Another possibility for why ng-click does not fire, is that you are apply a CSS style of pointer-events:none; to the element. I discovered that Bootstrap's form-control-feedback class applies that style. So, even though it raises the z-index by 2 so that the element is in front for clicking, it disables mouse-clicks!
So be careful how your frameworks interact.
As mentioned, the function should be created inside the scope:
$scope.deleteRecord = function (docURL) {
console.log(docURL);
$http.delete(docURL);
}
To use the function, first drop the "{{ }}" since you are using it from inside an ng-repeat. Another issue is the use of apostrophe in your code, you have two pairs one inside the other... well I am sure you get the problem with that.
Use the function like so:
ng-click="deleteRecord(d['#link'].href)"
Best of luck !
If you want to use as a submit button the set the type to 'submit' as:
<button type="submit" ...

Categories