Binding expression in ng-repeat - angularjs

I have the list of items
<ul>
<li><a>ItemA</a></li>
<li><a>ItemB{{vm.count}}</a></li>
</ul>
I am preparing the list in angular in Controller:
vm.listofItems =[{"textDisplay":"ItemA","Statego":""},
{"textDisplay":"ItemB{{vm.count}}","Statego":""}];
After some service call I'll get vm.count value? how to Bind now.

Ok just try this code, First of all i will suggest you to use $scope. I have assigned your listOfItems in watch of count, it will work for you, whenever you change the value of $scope.count
$scope.count;
$scope.$watch('count', function() {
$scope.listofItems =[
{"textDisplay":"ItemA","Statego":""},
{"textDisplay":"ItemB" +$scope.count,"Statego":""}
];
});

In Html
<div ng-app="app">
<div ng-controller="MainCtrl as main">
<ul>
<li ng-repeat='list in main.listofItems'>
{{list.textDisplay}}
</li>
</ul>
<input ng-model='main.count' ng-value='main.count'> {{main.count}}
</div>
</div>
In controller
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.count = 90;
vm.listofItems = [{
"textDisplay": "ItemA",
"Statego": ""
}, {
"textDisplay": "ItemB " + vm.count + "",
"Statego": ""
}];
$scope.$watch(angular.bind(this, function() {
return this.count;
}), function(newVal) {
vm.listofItems[1].textDisplay = "ItemB " + newVal;
// console.log(' change ' , newVal);
});
});
This the solution I figured out.Is this approach is correct?
jsFiddle for the same: https://jsfiddle.net/nj5/ve4xmhtj/

Related

AngularJS - Watch filtered list for changes

Within angular I have a filtered list of people that takes the filter criteria from a predicate function. I want to watch a variable of the filtered list (called filteredPeople) every time the filtered list changes. But I am unable to see when that variable changes.
My code is below:
HTML:
<ul>
<li ng-repeat="person in ($ctrl.filteredPeople = ($ctrl.people | filter: $ctrl.filter))">
...
</li>
</ul>
JS:
controller: ['$scope',
function ($scope) {
var $ctrl = this;
$ctrl.people = {...}
$ctrl.filteredPeople = [];
$scope.$watch($ctrl.filteredPeople, function () {
console.log("called"); //not being called
});
$ctrl.filter = function (p) {
//custom filter function for each item in the array of people
}
}]
I can answer any questions of provide more code if needed
angular.module('app', []).controller('ctrl', function($scope) {
var vm = this;
vm.items = [
{ name: 'Sam' },
{ name: 'Max' },
{ name: 'Tom' },
{ name: 'Henry' },
{ name: 'Jack' },
{ name: 'Kate' }
]
var counter = 1;
$scope.$watchCollection('vm.filtered', function(){
console.log('Changed' + counter++);
})
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<div ng-app='app' ng-controller='ctrl as vm'>
<input type='text' ng-model='vm.filter' />
<ul>
<li ng-repeat='item in vm.filtered = (vm.items | filter : vm.filter)'>{{item}}</li>
</ul>
</div>

angularjs show/hide tabs

Here i am displaying tabs from array using angularjs and bootstrap.
What i want is when i click on particular tab it should display content of that tab only.
i.e(When i click on dynamic-2 i want to display content of dynamic 2 and hide the content of dynamic-1 and dynamic-3 tab)
Right now i am getting content of all tabs on clicking.
js file
var items=[
{
Name:"tab1",
id:1,
content:"FirstTab",
title:"Dynamic-1",
templateUrl:"first.html"
},
{
Name:"tab2",
id:2,
content:"SecondTab",
title:"Dynamic-2",
templateUrl:"second.html"
},
{
Name:"tab3",
id:3,
content:"ThirdTab",
title:"Dynamic-3",
templateUrl:"third.html"
}
];
}]);
html file
<ul class="nav nav-tabs">
<li ng-repeat="l in list" >
<a href="#firsttab" ng-click="tab = 1" data-toggle="tab" >
{{l.title}} </a>
<div class="tab-content" >
<div id="firsttab" ng-click="tab = 1" ng-
show="tab===1">
Id: {{l.id}} <br>
Name: {{l.Name}} <br>
Content: {{l.content}} <br>
TemplateFile: <div ng-include="l.templateUrl"></div>
</div>
</ul>
</div>
</li>
model.js(Just change the code of this file with the code I have written below. It will give you desired result)
We have to provide delay to broadcast to make it work.
define(['jquery','ocLazyLoad','cssinjector'], function() {
var app=angular.module('App', ['angular.css.injector','oc.lazyLoad']);
app.controller('mycontroller', ['$scope','$ocLazyLoad','cssInjector','$rootScope','$timeout',
function($scope,$ocLazyLoad,cssInjector,$rootScope,$timeout) {
alert("modal-loaded");
$ocLazyLoad.load("http://localhost:8080/tabs/js/modal1.js")
.then(function(){
alert("modal1 loaded");
$scope.view="http://localhost:8080/tabs/view.html";
cssInjector.add("http://localhost:8080/tabs/style.css");
});
// ARRAY
var items=[
{
Name:"tab1",
id:1
},
{
Name:"tab2",
id:2
},
{
Name:"tab3",
id:3
}
];
$timeout(function(){
$rootScope.$broadcast('itmObj', items);
},0);
}]);
angular.element(function() {
angular.bootstrap(document, ['App']);
});
});
If you broadcast like this in parent controller
$scope.$broadcast('itmObj',{ itemsArray: items});
Then you can use the on-catch in child controller like
and you eill have the items array in args.itemsArray
$scope.$on('itmObj', function (event, args) {
var x = args.itemsArray; // args.itemsArray is your items from parentcontroller
});
Trying to add a promise on lazyloading the modalController and modal view will look like this
Modal.js
define(['jquery','ocLazyLoad','cssinjector'], function() {
var app=angular.module('App', ['angular.css.injector','oc.lazyLoad']);
app.controller('mycontroller', ['$scope','$ocLazyLoad','cssInjector',
function($scope,$ocLazyLoad,cssInjector) {
alert("modal-loaded");
// ARRAY
var items=[{
Name:"tab1",
id:1
},{
Name:"tab2",
id:2
},{
Name:"tab3",
id:3
}];
var lazyLoadModal1 = function(){
var deferred = $q.defer();
$ocLazyLoad.load("http://localhost:8080/tabs/js/modal1.js")
.then(function(){
alert("modal1 loaded");
$scope.view="http://localhost:8080/tabs/view.html";
cssInjector.add("http://localhost:8080/tabs/style.css");
deferred.resolve();
},function(){
deferred.reject();
});
return deferred.promise;
};
var init = (function(){
lazyLoadModal1().then(function(){
$scope.$broadcast('itmObj', {item:items});
});
})();
}]);
View.html
<div ng-controller="modalcontroller">
<div ng-repeat="vm in itemsArray">
<p>{{vm.Name}}</p>
<p>{{vm.id}}</p>
</div>
</div>
Modal1.js
angular.module('App', ['angular.css.injector','oc.lazyLoad'])
.controller("modalcontroller", ['$scope','$ocLazyLoad','cssInjector',
function($scope,$ocLazyLoad,cssInjector){
alert("In modal Controller");
$scope.$on("broadcast-started", function (event, data){
$scope.itemsArray=data.item;
console.log($scope.itemsArray);
});
}]);

Parsing Json Array in AngularJS

Iam newbie in angularjs.How to display the json in html using angularjs.Below is the code
var app = angular.module('myapp', []);
app.controller('myctrl', function($scope, $http) {
$http.get("http://localhost:8080/xyz").then(function (response) {
});
});
Reponse is :
[
{
"city": "animal"
},
{
"city": "bird"
}
]
In your controller you should assign your json to a scope:
app.controller('myctrl', function($scope, $http) {
$scope.myArray = [];
$http.get("http://localhost:8080/xyz").then(function (response) {
$scope.myArray = response;
});
});
Then in your view, you can do something like:
<div ng-controller="myctrl">
<ul ng-repeat="obj in myArray">
<li>{{obj.city}}</li>
</ul>
</div>
use ng-repeat like this.
<div ng-repeat="t in test">
<span>{{t.city}}</span>
</div>
plunker here
Use the following code this might help you.
myArray = JSON.parse(response);
for ( var index in myArray ) {
var singleObject = myArray[index];
var keys = Object.keys[singleObject];
for ( var j in keys ) {
console.log("Value of key"+j+"is"+keys[j]+"in Object"+index);
}
}
Here response is a string value.
Try this
Where Records is like this..
{"records":[{"ID":"235","user_id":"2","project_id":"186","project_cid":"2900669120142632939","imagePath":"media/pano/sv_02a29.jpg","ImageName":"1.jpg"},{"ID":"236","user_id":"2","project_id":"186","project_cid":"2900669120142632939","imagePath":"media/pano/sv_f0f59.jpg","ImageName":"253.jpg"},{"ID":"239","user_id":"2","project_id":"186","project_cid":"1997319193267363957","imagePath":"media/pano/sv_6536f.jpg","ImageName":"PANOCLOUD_meta.jpg"},{"ID":"240","user_id":"2","project_id":"186","project_cid":"6736594884768838469","imagePath":"media/pano/sv_898ca.jpg","ImageName":"Boscolo Hotel Budapest.jpg"}]}
$http.get("moderatorData.php").then(function (response) {
$scope.panoramas = response.data.records;
});
Then print using like this
<li class="align" ng-repeat="pano in panoramas>
<img ng-src="{{pano.imagePath}}" style="height: 90px;" />
</li>

Factory value not updated in model ...what I am doing wrong?

I am new to angular-js. I have two controllers (welcomeContoller,productController) and both handling the same model within the factory.
When the model getting updating by one controller(productController) it should reflect the update in another controller. (welcomeContoller)
But its not happening now.
HTML code :
<body ng-app="myApp">
<div ng-controller="welcomeContoller">
{{totalProductCnt}}
</div>
<div ng-controller="productController">
<div class="addRemoveCart">
<span class="pull-left glyphicon glyphicon-minus" ng-click="removeProduct()"></span>
<span class="pull-right glyphicon glyphicon-plus" ng-click="addProduct(1)"></span>
</div>
</div>
JS code
var myApp = angular.module("myApp", ['ui.bootstrap']);
myApp.factory("productCountFactory", function() {
return {
totalProducts:0
};
});
myApp.controller("welcomeContoller", function($scope, productCountFactory)
{
$scope.totalProductCnt = productCountFactory.totalProducts;
});
myApp.controller("productController", function($scope, productCountFactory) {
$scope.addProduct = function() {
productCountFactory.totalProducts++;
alert(productCountFactory.totalProducts);
};
$scope.removeProduct = function() {
if(productCountFactory.totalProducts >=1)
productCountFactory.totalProducts--;
alert(productCountFactory.totalProducts);
};
});
Even after the addProduct is called the totalProductCnt is displaying as zero. I want to display the value for each increment.
Plunkr Link
Put the factory object reference on scope:
myApp.controller("welcomeContoller", function($scope, productCountFactory) {
$scope.productCountFactory = productCountFactory;
});
Watch the property of the object.
{{productCountFactory.totalProducts}}
The DEMO on PLNKR.
By putting a reference on scope, on every digest cycle the watcher looks up the value of the property and updates the DOM if there is a change.
The totalProductCnt from your welcomeController isn't updated because it is assigned only once when the controller is created.
You can use several solutions to refresh the displayed value. Use a getter for your totalProducts in the factory :
myApp.factory("productCountFactory", function() {
var totalProducts = 0;
return {
getTotalProducts: function() {
return totalProducts;
},
addProduct: function() {
totalProducts++;
},
removeProduct: function() {
totalProducts--;
}
};
});
myApp.controller("welcomeContoller", function($scope, productCountFactory) {
$scope.getTotalProducts = productCountFactory.getTotalProducts;
});
myApp.controller("productController", function($scope, productCountFactory) {
$scope.addProduct = function() {
productCountFactory.addProduct();
};
$scope.removeProduct = function() {
if (productCountFactory.getTotalProducts() >= 1)
productCountFactory.removeProduct();
};
});
And update the view accordingly:
<div ng-controller="welcomeContoller">
{{getTotalProducts()}}
</div>
Plunkr Link

store key in a variable for each ng-repeat

I am fairly new to angular js.
I have two different scope data in my controller ($scope.itemdata & $scope.skudata, both are simplified in the plucker). Both are guaranteed to have the same structure for any key.
I have a nested ng-repeat for item data and I want to store/keep a track of keys inside each ng-repeat so that I can use the path variable to get the value out of skudata.
Problem: {{path}} expression in HTML is not resolving to correct key value.
Looking at the console log the keys are added and removed in the correct order.
I am not sure where I am going wrong.
Here is plucker : http://plnkr.co/edit/0q8tZ9JLsGdfR03YbpYB?p=info
HTML Code:<body ng-controller="MainCtrl">
<p>Hello</p>
<script type="text/ng-template" id="field_renderer.html">
<div ng-init="addkeyToPath(key)"></div>
{{key}}
{{value}}
<!--output should be skudata.value but instead its skudata-->
{{path}}
<div ng-init="removeKeyFromPath(key)"></div>
{{path}}
</script>
<div>
<div ng-repeat="(key ,value) in itemData" ng-include="'field_renderer.html'"></div>
</div>
Controller Code:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.path = 'skudata';
$scope.isThisAnObject = function(input) {
return angular.isObject(input) ? true : false;
}
$scope.addkeyToPath = function(input) {
console.log("Adding");
console.log($scope.path);
$scope.path = $scope.path + "." + input;
console.log($scope.path);
};
$scope.removeKeyFromPath = function(input) {
console.log("remove");
console.log($scope.path);
$scope.path = $scope.path.substring(0,$scope.path.lastIndexOf("."));
console.log($scope.path);
};
$scope.itemData =
{ value:'item_name',
length:'10'
};
$scope.skudata =
{ value:'sku_name',
length:'20'
};
});
The problem is that you're using the $scope path variable, when really you want to display path variable of the item itself. Make a few changes to get this working plunkr
Template:
<div ng-init="addkeyToPath(this, key)">
{{key}}: {{value}}
{{path}}
</div>
Controller:
$scope.addkeyToPath = function(item, input) {
item.path = $scope.path + "." + input;
};
$scope.itemData = {
value:'item_name',
length:'10'
};

Resources