Alternative to using ng-init in 'view'? - angularjs

I am trying to create a 'like' function for my app. I want to be able to set the value of a dynamically generated number as the 'like count'. The problem comes in using 'ng-init', as the documentation says this is a bad way to do it!
How do you set the value in the 'controller' rather than the 'view'?
Here is what I have so far:
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<article ng-repeat="feed in feeds">
<h3>{{feed.createdby}}</h3>
<p>{{feed.content}}</p>
<button ng-click="likeClicked($index)">{{isLiked[$index]|liked}}</button>
<span ng-init="likeCount=feed.likes.length">{{likeCount}}</span>
</article>
</body>
</html>
Thanks,
JP

Just change
`<span ng-init="likeCount=feed.likes.length">{{likeCount}}</span>`
per
`<span>{{feed.likes.length}}</span>`.
If you still need the count in the controller for some other reason (which I can't see), create a controller, let's assume FeedCtrl, and add it to your article:
<article ng-repeat="feed in feeds" ng-controller="FeedCtrl">
...
<span>{{likeCount}}</span>
</article>
And your FeedCtrl would be:
function FeedCtrl($scope) {
$scope.$watch('feed.likes.length', function(newValue) {
$scope.likeCount = newValue;
});
}
Yet another approach would be create a function to resolve you the value:
<article ng-repeat="feed in feeds" ng-controller="FeedCtrl">
...
<span>{{likeCount()}}</span>
</article>
function FeedCtrl($scope) {
$scope.likeCount = function() {
return $feed && $feed.likes ? $feed.likes.length : undefined;
};
}

If your feeds object/array is long, it's better to use ng-bind for performance reasons.
<span ng-bind="likeCount"></span>
rather than
{{likeCount}}

Related

Angular.js - Changing an Element's CSS by clicking another Element

I'm very new to Angular.js.
I'm grabbing images from a MySQL database and printing them to the screen like this:
while ($row = mysqli_fetch_array($result)){
echo "<div id='img_div' ng-click='popup()'>";
On the echoed div, I have an ng-click. In app.js, this is currently what I have for the ng-click (purely for testing purposes:
$scope.popup = function() {
// assign a message to the $scope
$scope.message = 'Hello World!';
// use the $log service to output the message in a console
$log.log($scope.message);
};
What I'd actually like to have in that ng-click function is:
modal.style.display = "block";
I'd basically like to set the CSS of another element.
Will I need to apply ng-style in order to do this?
Using ng-style with a $scope variable you can control the display property (or any for that matter):
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.display = 'inline';
$scope.setDisplayValue = function(value){
$scope.display = value;
}
});
div#test {
background: red;
}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div id="test" ng-style="{'display' : display}">{{display}}</div>
<hr />
<button ng-click="setDisplayValue('inline')">Set Display to inline</button>
<button ng-click="setDisplayValue('block')">Set Display to block</button>
</body>
</html>
Plunker mirror: http://plnkr.co/edit/4vR4SEnz7iX81CWIrShw

how to apply class in DOM using value returned from a function in angularJS?

I have my DOM element as :
<i id= class="icon clr-org fleft ion-bookmark" ng-class="{business.class : setFavouriteBusinessIcon(business.ID, $index)}"></i>
now I want to apply business.class which is a variable in my scope as the element's class whenever setFavouriteBusinessIcon(business.ID, $index) returns true.
but the current ng-class condition is not working.
You can do so by having single quotes and {{...}} around it. Like this:
<i ng-class="{'{{business.class}}' : setFavouriteBusinessIcon(business.ID, $index)}"></i>
Here's a working example: (notice that world class has been applied and so is its CSS)
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'world';
});
.world {
background-color: red;
}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
</head>
<body ng-controller="MainCtrl">
<p ng-class="{'{{name}}': true}">Hello {{name}}!</p>
</body>
</html>

Angular ng-confirm-click doesn't work

Could you please explain why my ng-confirm-click doesn't work?
<div ng-controller="MainCtrl" ng-init="show=true;">
<p >Hello {{name}}!</p>
<button ng-show="show" confirmed-click="changes();show=false;" ng-confirm-click="Confirm change?">change</button>
</div>
I need to hide the button.
Here the example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-app = "plunker">
<div ng-controller="MainCtrl" ng-init="show=true;">
<p >Hello {{name}}!</p>
<button ng-show="show" confirmed-click="changes();show=false;" ng-confirm-click="Confirm change?">change</button>
</div>
</body>
</html>
Try this working code,
Inside html:
<div ng-confirm-click="Are you sure to delete this product ?" confirmed-click="deletePost(data.postId)"> <span class="glyphicon glyphicon-trash"></span></div>
In app.js file, put the below code(without any change):
app.directive('ngConfirmClick', [
function(){
return {
link: function (scope, element, attr) {
var msg = attr.ngConfirmClick || "Are you sure?";
var clickAction = attr.confirmedClick;
element.bind('click',function (event) {
if ( window.confirm(msg) ) {
scope.$eval(clickAction)
}
});
}
};
}])
Use scope.$apply instead of scope.$eval and remove unnecessary scope.$apply from controller.
From documentation:
This use of $eval: scope.$eval() seems to be deprecated in favor of scope.$apply to execute a function that uses and modifies the scope, and update the view later.
Plunker

How to set html id tag dynamically through angularjs?

I know I can set html src tag like <img ng-src="{{phone.imageUrl}}">. But how can I set an id tag like <span id="sourceId::{{post.id}}" class="count"></span> ?
I tried <span id="{{ 'sourceId::'post.id }}" class="count"></span> but it didn't work.
It worked for me.
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.13/angular.js" data-semver="1.3.13"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<span id="{{name}}" class="count">Jeinsh</span>
</body>
</html>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
here is working plunk => link
Inspect the element in developer tool on span and you will get updated id there.
As #karaxuna said, the following should work
id="sourceId::{{post.id}}"
Or doing the string concatenation inside the {{}} with a +
id="{{'sourceId::' + post.id}}"

Angular live search filter on row iterator

I have a template in which I have rows, and there are two elements in each row and each element has different classes so I have my Html structure like so (simplified)
<div ng-repeat "row in deals">
<div class="deal-title-left">{{row[0].title}}</div>
<div class="deal-title-right">{{row[1].title}}</div>
</div>
I would like to add a search box feature that will use live search to go through the deal titles. I have tried using the ng-model="search" and adding a search filter into the row div, but how do I apply the model to each individual deal instead of the entire row?
Demo :http://plnkr.co/edit/zGYLPcPHTr1TOSZTIBI2?p=preview
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link href="style.css" rel="stylesheet" />
<script data-semver="1.2.21" src="https://code.angularjs.org/1.2.21/angular.js" data-require="angular.js#1.2.x"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<input type="text" ng-model="search"/>
<div ng-repeat="row in deals | filter :{title:search}">
<div class="deal-title-left">{{row.title}}</div>
</div>
</body>
</html>
JS:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.deals = [{
title: "Cola for free"
}, {
title: "Icecream for free"
}, {
title: "Tee for free"
},
]
});

Resources