I need to show/hide a tab based on the value of JSON, i.e. If the value of Region (In JSON, 'Region':'US') is equal to US in at least one of the items within JSON response I should show the tab, if not hide...
I'm using the following code to check if at least the item.region has US value, I'm able to read the values from the JSON but when I try to set the value to true to a variable inside the tag I don't get the value in the variable
<span ng-repeat="item in res.objects" ng-if="item.region === 'US'">
// Set myVariable = true
</span>
And after the variable has been set, display the div with ng-show and the value of the bool variable.
<div class="action-tab" ng-click="res.viewUS()" ng-show="<valueOfBoolVariable">
View US
</div>
Is this good approach to accomplish this? Any idea would be appreciated.
try using ng-init it allows you to evaluate an expression of your current scope
<span ng-repeat="item in res.objects" ng-if="item.region === 'US'">
<!-- Evaluate your variable -->
<div ng-init="evaluate(item)"> </div>
</span>
In your controller
$scope.evaluate = function(item){
//you do the job
}
Related
Consider the code given below :
<li ng-repeat="task in tasks track by $index" >
<input ng-model="task.completeStatus" ng-click="updateOnClick()"
type="checkbox"
style="margin-right: 20px;" />
<span class="{{task.completeStatus}}" ng-dblclick="editTaskMessage()"
contenteditable="false" ng-model="task.taskMessage"
ng-keydown="enterEdit()">
{{task.taskMessage}}
</span>
</li>
My problem is, how can I access the ng-model="task.completeStatus" in the controller...? ( I tried to access the value returned from the ng-model in the controller as $scope.task.completeStatus but gives an error as TypeError: Cannot read property 'completeStatus' of undefined ) and can the ng-model directive be used to overwrite or modify currently existing values in the tasks array inside the controller.??
In your first question, you are getting the error because you are trying to access the property of array inside array without its index.
You can access the "task.completeStatus" in the controller by passing the $index of the array in tasks as below
ng-click="updateOnClick($index)"
And in the controller, you can access the "task.completeStatus" as below
function updateOnClick(index){
var completeStatus = $scope.task[index].completeStatus);
}
Yes, you can modify the values present in task array in the controller, as ng-model provides two way binding of variables which means that you can change the value of the angular variable from the controller as well as from HTML.
i have a common block with ng-repeat:
<div ng-repeat="(position, task) in Tasks.plannedTasks">
{{(task.plan - (TasksTimeSpent[task.id][task.worker]).toFixed(2)}}
</div>
And now i need to set background if :
{{(task.plan - (TasksTimeSpent[task.id][task.worker]).toFixed(2)}} < 0
task.plan and task.worker can be changed and after this need to check if statement and change shown value
Is it possible to save expression result in variable (for example : curDif), display this variable and check variable inside if? I don't want calculate expression twice.
The way to calculate variable in controller is bad because variable is useless for application logic and need only for displaying but for using controller if task changes - i need to recalculate variable and use watcher for Task.
You can use ng-init for that:
<div ng-repeat="(position, task) in Tasks.plannedTasks">
<ng-init ng-init="curDif = (task.plan - (TasksTimeSpent[task.id][task.worker]).toFixed(2)">
{{curDif}}
</ng-init>
</div>
You may want to use ng-class as well to set the background.
<div ng-repeat="(position, task) in Tasks.plannedTasks">
<div ng-init="curDif = task.plan - (TasksTimeSpent[task.id][task.worker]).toFixed(2)" ng-class="'my-background':curDif < 0">
</div>
</div>
Then style your background using CSS.
When I load a page to display items prices, before the prices are calculated in the controller the page displays "null" in the price for a while (maybe 1 sec). How can I avoid this? I thought this is the purpose of ng-init, is it right?
When I use it, I get my items initialized to 0. This is ok. However, when the value is calculated the price is not updated.
Example:
<div class="text-right custom_block_field" ng-show="booking.duration == 0" ng-init="itemSelected.convertedPrice = 0">{{(itemSelected.convertedPrice)}}</div>
ng-init is not for that, it is basically used to call a method or some initialization of the values
<div class="text-right custom_block_field"
ng-show="booking.duration == 0"
ng-bind="itemSelected.convertedPrice"></div>
Or use the ng-cloak with parent element
ng-cloack is the best way. It'll mask a value until it's ready.
<div ng-cloak>
//whatever your app code is
</div>
I have a ng-repeat loop, used in combination with ng-switch and ng-bind (I assume ng-switch is not the problem here).
<div ng-repeat="message in messages track by message.id">
<div ng-switch="message.yesno">
<div ng-switch-when="true">
text 1
</div>
<div class="click-me" element_id = "{{message.id}}" ng-switch-when="false" ng-bind="message.texts[message.active_text]">
</div>
</div>
</div>
messages is defined as an array of objects with the following structure:
{
id: int,
yesno: boolean,
texts: array, // containing N strings
active_text: int // index of the current displayed string
}
in addition to a setter method (which is within the same function which returns the object, let's say this function is the object constructor)
this.setNextText = function(){
this.active_text= (++this.active_text)%(this.texts.length);
}
When yesno property of message object is false, the user can click on the text and change it to the next available text (and then back to the original one when the array bonduary is reached).
so, when the user clicks on the text, the following event is triggered:
$(document).on("click",".click-me",function(){
var message_id = $(this).getAttribute("element_id");
$.grep($scope.messages, function(e){ return e.id == message_id; })[0].setNextText(); // obj containing the message
});
which basically:
takes the index on the clicked messages (corresponding to the index of the current ng-repeat loop)
increases it
This way, nd-bind should bind the next text available in message.texts.
However, it doesn't.
I'm pretty sure that:
ng-bind: is set up correctly (the first element of message.texts is printed correctly)
message.active_text is updated correctly
Also, I tried to use:
$scope.apply();
but I even get an error (usually it works):
Uncaught TypeError: $scope.apply is not a function
Any clue?
The Select tag I am using in conjunction with ng-switch does not properly display nor function properly after being set once.
<select ng-model="visuals" ng-options="visual for visual in visuals">
See JSFiddle:
http://jsfiddle.net/timothybone/UaFuc/3/
Thanks in advance!
:D
You should not bind visuals using ng-model as it is the list of items. Setting it replace the list value by the chosen item (which is a list of characters). Causing the strange behaviour.
<select ng-model="item" ng-options="visual for visual in visuals">
This new variable must be declared in the scope. It is also used to set an initial value:
$scope.item = 'none';
Your switch usage was also wrong, you need en enclose condition in the switching block.
<div ng-switch on="item">
<span ng-switch-when="lots">Youtube</span>
<span ng-switch-default></span>
</div>
If you want to set the content of the HTML using ng-bind-html-unsafe you should provide a variable as parameter (not sure how you could inject javascript that way).
<span ng-switch-when="lots" ng-bind-html-unsafe="youtube">Could not evaluate 'youtube' variable</span>
The span content is then replaced. Of course a new variable must be defined in the scope to hold the HTML content:
$scope.youtube = "<hr/>This is an HTML content<hr/>";
I updated the jsFiddle: http://jsfiddle.net/PMpLa/4/