I'm using Angular JS. I loop out a part of a scope that from the start is a JSON array.
I need to check for if a value in that array exists. If it does it should do something. The following code work but I can't figure out a way to save "status" temporary.
<div ng-repeat="item_value in item['slug'].values">
{{item_value}}
<div ng-if="item_value == 'dogs_cats'">
Somehow save "status" to true when above is equal.
</div>
</div>
<div ng-if="status == 'true'">
Do someting here.
</div>
Maybe my approach is wrong. Maybe this should not go in the template? I like different solutions to choose from and suggestions on which would be prefered.
I think something like this would do:
<div ng-if="item_value == 'dogs_cats'" ng-init="status = true">
Somehow save "status" to true when above is equal.
</div>
But preferably you should put that logic in controller
You should refactor some of this into a controller. Try something like:
HTML:
<div ng-controller='itemSlugs'>
<div ng-repeat="item_value in item['slug'].values">
{{item_value}}
</div>
<div ng-if="status">
Do something here.
</div>
</div>
Javascript:
angular.module('myApp', []).
controller('itemSlugs', ['$scope', function($scope){
$scope.item.slug.values = [ /*initialize here*/ ];
$scope.status = false;
$scope.$watch('item.slug.values', function(){
$scope.status = false;
$scope.item.slug.values.forEach(function(item_value){
if (item_value == 'dogs_cats'){
$scope.status = true;
}
});
});
});
I added a watch so if any values in your item.slug.values changes, then the status will update accordingly.
Related
I have a constant file which looks like this
demo.constant.js
// Add detail constans here
(function () {
angular.module('myApp').constant('TYPE', {
DYNAMIC: 'dynamic',
STATIC: 'static'
});
}());
Now I have a controller file that looks similar to this.
demo.controller.js
(function() {
var DemoController = function(DEP1,DEP2, .... , TYPE)
console.log(TYPE.DYNAMIC); // works perfectly
var self = this;
self.type = '';
...
...
angular.module('myApp.controllers').controller('DemoController', DemoController);
})();
I am trying to access these constants in the HTML file like this:-
<div ng-controller="DemoController as self">
<span ng-if="(self.type === 'dynamic')"> <!--instead of 'dynamic' I want to use TYPE.DYNAMIC-->
...
...
...
</span>
</div>
Note:- {{self.type}} works but {{TYPE.DYNAMIC}} doesn't.
Another problem is that I want to use this constant as the value of radio buttons.
somewhat like this:-
<input type="radio" name="type" ng-model="self.inputType" value="dynamic"> <!-- Here I want to use TYPE.DYNAMIC -->
<input type="radio" name="type" ng-model="self.inputType" value="static"> <!-- Same as above -->
I have searched everywhere but nothing seems to work. Please Help!!
One approach is to assign the constant to a controller property:
function DemoController(DEP1,DEP2, /*.... ,*/ TYPE) {
console.log(TYPE.DYNAMIC); // works perfectly
this.TYPE = TYPE;
}
angular.module('myApp.controllers').controller('DemoController', DemoController)
Then use it in the template:
<div ng-controller="DemoController as $ctrl">
<span ng-if="$ctrl.type === $ctrl.TYPE.DYNAMIC">
...
</span>
</div>
Note: The ng-if directive uses creates a child scope. Consider instead using the ng-show directive which uses CSS and less resources.
You can use $rootScope and initilize it in run phase:
angular.module('app')
.run(function ($rootScope, TYPE) {
$rootScope.TYPE = TYPE
});
then you can use it directly in your HTML
I have angularjs ui-grid, i used below condition to check availability of data, which means if data is not there i am showing 'no data available' message.
The problem is my api call is little slow because of huge data, so while this call in process no data available will show, I need to hide it in angular way initially. I cant use disply:none initially because there are so many conditions in grid filter after which that message will have to show, so every time i cant say disaply:none and display:block. Any help will be very helpful thank you.
html
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-selection ui-grid-exporter class="grid">
<div class="watermark" ng-show="!gridOptions.data.length">No data available</div>
</div>
</div>
Sample js call
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json')
.success(function(data) {
data = {"data": []};
$scope.gridOptions.data = data;
});
Please see the demo in below plunker
Add a new variable in controller:
$scope.noData = false;
Change your api call as:
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500.json')
.success(function(data) {
if (data.length > 0) {
$scope.gridOptions.data = data;
} else {
$scope.noData = true;
}
});
in the view change:
<div class="watermark" ng-show="noData">No data available</div>
Test Plunker
Easy doing by using another state handler variable e.g. $scope.loading:
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-selection ui-grid-exporter class="grid">
<div class="watermark"
ng-show="!gridOptions.data.length && !loading">No data available</div>
<div class="watermark"
ng-show="loading">loading ...</div>
</div>
</div>
Controller
$scope.loading = true;
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json').success(function(data) {
$scope.loading = false;
data = {"data": []};
$scope.gridOptions.data = data;
});
1) plnkr Demo
2) plnkr Demo (inlcuding a little timeout)
I am trying to compare the value passed from the url to a controller to a field in a json file.
galleryItem.html
<div class="filter-box">
<ul class="filter list-inline text-center" ng-repeat="gal in ParentData">
<li></li>
</ul>
</div>
<div class="container-fluid">
<div class="row">
<div class="portfolio-box" ng-repeat="x in data">
<div class="col-sm-4">
<div class="item-img-wrap">
<img ng-src={{x.url}} class="img-responsive" alt="">
<div class="item-img-overlay">
<a href={{x.url}} class="show-image">
<span></span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The updated controller:
controllers.controller('GalleryViewCtrl', function GalleryViewCtrl($scope, $http, $stateParams) {
$scope.pageName = '';
$scope.Description = '';
$scope.GalleryID = $stateParams.id;
$http.get('/data/galleryItems.json')
.then(function (response) { $scope.ParentData = response.data.galleries });
$http.get('/data/galleryItemImages.json')
.then(function (response) {
$scope.data = response.data.images.galleryIdentifier === $stateParams.id;
});
});
I verified the correct value is being passed in to the controller, the values are static and so is the data being passed from the json file. I placed an if statement to check for null as suggested as well. I removed it temporarily to reduce what I'm working with.
If I remove the === $stateParams.id i get all of the images returned and displayed correctly.
If I replace $stateParams.id with a value that I know is in the list (4 or '4') i do not get anything returned. I also tried the value for the last item in the list.
There are no errors (loading scripts, reading json etc.) and all of the values are correct when I'm debugging.
I am still new to this and there is so much documentation with different solutions it all gets very confusing. If anyone has any ideas they would be greatly appreciated.
You are loading data to the $scope.data when the ajax call returns some data. I am assuming your view code is calling the galleryFiltered even before that. May be try to add a null check before returning the value from the method.
$scope.galleryFiltered = function () {
if($scope.data!=null)
{
return $scope.data.galleryIdentifier === $scope.GalleryID;
}
return false;
};
Remember that $http service returns a promise so your $scope.data will be undefined (or holding current state) until $http.get('/data/galleryItemImages.json') will return a success callback function and assign new value to $scope.data from response.
If you'll run $scope.galleryFiltered() before promise gets resolved you will have $scope.data == undefined or whatever data is stored on $scope.data at the time or $scope.galleryFiltered() execution.
I have following function:
$scope.setDetailToScope = function(data) {
$scope.$apply(function() {
//$scope.order = data;
$rootScope.order = data;
setTimeout(function() {
$scope.$apply(function() {
//wrapped this within $apply
$scope.order = data[0];
console.log('message:' + $scope.order);
console.log($scope.order);
});
}, 100);
});
};
"
console.log($scope.order);
Gives me values which has been set into scope.
But i cannot get these values in template.
<!-- DEBUG DIV -->
<div class="debugDiv" ng-show="$root.debugable == true">
{{columns}}
</div>
<div data-ng-controller="OrdersCtrl" ng-init="initData()">
<div id="orders_grid" >
</div>
</div>
<!-- GRID TOOLBAR BUTTON TEMPLATE -->
<script id="template" type="text/x-kendo-template">
<a class="k-button" href="\#/orders/create">Add</a>
</script>
<!-- ORDER DETAIL DIV -->
<div class="container" id="orderDetail" data-ng-controller="OrdersCtrl" ng-if="'detailSelected == true'" xmlns="http://www.w3.org/1999/html">
<!-- DEBUG DIV -->
<div class="debugDiv" ng-show="$root.debugable == true">
{{order}} <!--NOT WORKING-->
</div>
If i tried to add values into rootscope it works, but in this case i cannot get value into ng-model.
What i'm doing wrong please?
Many Thanks for any help.
EDIT:
If i tried solution wit $timeout i got on console.log($scope.order);
following object which is not passed into the template:
_events: ObjectacrCrCode: "interlos"actionName: ht.extend.initarchived: falsebaseStationInfo: ht.extend.initbsc: "bsc1"btsRolloutPlan: "plan1"candidate: "B"costCategory: ht.extend.initcreatedBy: ht.extend.initdirty: falsefacility: ht.extend.initid: 3location: ht.extend.initmilestoneSequence: undefinednetworkType: "Fix"note: "poznamka"orderNumber: 111113orderType: ht.extend.initotherInfo: ht.extend.initparent: function (){return e.apply(n||this,r.concat(h.call(arguments)))}partner: ht.extend.initpersonalInfo: ht.extend.initproject: ht.extend.initpsidCode: "psid1"sapSacIrnCode: "sap1"uid: "924c0278-88d0-4255-b8ac-b004155463fa"warehouseInfo: ht.extend.init__proto__: i
well I'm not sure why you are using a setTimeout with scope apply, to me is safer to use a $timeout since it fires another digest cycle,
try something like
$scope.setDetailToScope = function(data) {
$timeout(funtion(){
//$rootScope.order = data; try either data or data[0]
$scope.order = data[0];
},100);
};
please note that calling nested apply methods can run into some problems with the angularjs digest cycle you may get an error like "digest already in progress" so put attention to it.
NOTE:
it seems like you got some dirty data there, so try to do a map between the data and the scope
$scope.order ={};
$scope.order.uid = data.uid;
$scope.order.orderNumber = data.orderNumber //and so on
in your template try something like:
<div class="debugDiv">
<p> {{order.uid}} </p>
<p> {{ order.orderNumber}} </p>
</div>
this could be a little bit rustic but it worth to try it out.
Say, I have the following code:
<div ng-controller="postsController">
<div id = "post_id_{{post.postid}}" class = "post" ng-repeat="post in posts">
......
<div class="comments">
<div><span>{{post.totalcomments}}</span> Comments</div>
</div>
.......
</div>
</div>
and on page load this evaluates to something like:
<div ng-controller="postsController">
<div id = "post_id_1" class = "post">
......
<div class="comments">
<div><span>3</span> Comments</div>
</div>
.......
</div>
<div id = "post_id_2" class = "post">
......
<div class="comments">
<div><span>6</span> Comments</div>
</div>
.......
</div>
....and so on.....
</div>
How could I then (using a different controller?) update the DOM when there is a change in the post.totalcomments value for a particular post? I've got the backend worked out, and know you can use $timeout to have a controller repeat itself. I would do it with jQuery (messy but easy) like this (eg: post #1 had a new comment):
var newtotal = 4; //but really get the value from ajax call
$("#post_id_1 .comments span").html(newtotal)
But how would I do this with Angular? I don't want to re-display all the posts and the data, every time I check for updated with the server. Just have a controller (which refreshes with $timeout) and only update the changed fields as needed.
Thanks
If you want to refresh the data periodically use $interval rather than timeout, If its going to be only once after a certain perios say 10 seconds use $timeout. And you need not write a separate controller for this. This can be done within the same controller.
A simple interval demo for you,
Sample Demo: http://plnkr.co/edit/fj6crcHkxm6rkwJT9eGg?p=preview
JS:
app.controller('MainCtrl1', function($scope, $timeout, $http, $interval) {
$scope.comments = [{
total: 3,
comment: 'some comment 1'
}, {
total: 10,
comment: 'some other comment'
}];
$interval(function(){
//logic to update comments
$scope.comments[0].total++;
},1000);
$scope.updateCount = function(){
$scope.comments[1].total++;
};
});