I am trying to share data between two controllers (child1 and child2) which are children of one common controller (parent).
index.html is :
<div ng-controller="parent">
<ul>
<p>Parent controller</p>
<li ng-repeat="item in items">
{{item.id}}
</li>
</ul>
<div ng-controller="child1">
<ul>
<p>First DIV :</p>
<li ng-repeat="item in items">
{{item.id}}
</li>
</ul>
</div>
<div ng-controller="child2">
<ul>
<p>Second DIV :</p>
<li ng-repeat="item in items">
{{item.id}}
</li>
</ul>
</div>
</div>
I have defined three controllers as (parent, child1 and child2) :
var myApp = angular.module('myApp', []);
myApp.controller('parent',['$scope', function($scope) {
$scope.items = [
{'id':1},
{'id':2},
{'id':3},
{'id':4}
];
$scope.items.push({'id':10});
$scope.myfun = function() {
setTimeout(function(){
$scope.items.push({'id':20});
alert("inserting 20....!");
},3000);
}
$scope.myfun();
}]);
myApp.controller('child1', ['$scope', function($scope) {
$scope.items = $scope.$parent.items;
}]);
myApp.controller('child2', ['$scope', function($scope) {
$scope.items = $scope.$parent.items;
}]);
But the page is not showing anything. What is wrong with this code?
Use angular's $timeout service instead of setTimeout:
myApp.controller('parent',['$scope','$timeout', function($scope, $timeout) {
$scope.items = [
{'id':1},
{'id':2},
{'id':3},
{'id':4}
];
$scope.items.push({'id':10});
$scope.myfun = function() {
$timeout(function(){
$scope.items.push({'id':20});
alert("inserting 20....!");
},3000);
}
$scope.myfun();
}]);
Related
I'm using AngularJS 1.5.8.
I'm trying to bind {{card.reading}} in the view, but the data is rendered as text
html
<div ng-app="myApplication" ng-controller="postController as tarot">
<ul>
<li class="card" ng-repeat="card in tarot">
<img class="card" src="app/images/cards/{{card.value}}.png" alt="card.name">
<article>{{card.reading | unsafe}}</article>
</li>
</ul>
</div>`
JavaScript
var app = angular.module('myApplication', []);
app.controller('postController', function($scope, $http, $filter, $sce) {
$scope.$sce = $sce;
var url = './api.php/tarot';
$http.get(url).success(function(response) {
$scope.tarot = php_crud_api_transform(response).tarot;
});
});
app.filter('unsafe', function($sce){
return $sce.parseAsHtml;
});
exemple of JSON
{
"id":1,
"name": "Test",
"value": "1",
"reading": "<h2>Lorem Ipsum</h2><p>Lorem ipsum</p>"
}
Updating your HTML as such should do the trick..
<div ng-app="myApplication" ng-controller="postController as tarot">
<ul>
<li class="card" ng-repeat="card in tarot">
<img class="card" src="app/images/cards/{{card.value}}.png" alt="card.name">
<article ng-bind-html="card.reading"></article>
</li>
</ul>
</div>`
Thank you, it's solved now.
JavaScript
var app = angular.module('myApplication', ['ngSanitize'])
.controller('postController', ['$scope', '$http', '$sce',
function postController($scope, $http, $sce) {
var url = './api.php/tarot';
$http.get(url).success(function(response) {
$scope.tarot = php_crud_api_transform(response).tarot
});
$scope.explicitlyTrustedHtml = $sce.trustAsHtml();
}
]);
and the HTML as you suggested. :)
There is another solution . you can modify you code a little bit and it will work.
<div ng-app="myApplication" ng-controller="postController as tarot">
<ul>
<li class="card" ng-repeat="card in tarot">
<img class="card" src="app/images/cards/{{card.value}}.png" alt="card.name">
<article ng-bind-html="card.reading | unsafe"></article>
</li>
</ul>
</div>`
change your filter to ,
app.filter('unsafe', function($sce) {
return function(text) {
return $sce.trustAsHtml(text);
}
});
This will work.
How to append the new content in angulularJS template in ng -repeat without destroying previous content
1.I want to dispaly the myvar data in every save click
<script>
var myApp = angular.module('myApp', []);
myApp.controller('MyController', ['$scope', '$http', function ($scope, $http, $filter, $rootScope) {
$scope.view= function () {
//some ajax calll
$scope.myvar = data;
};
}]);
</script>
</head>
<body ng-app="myApp" ng-controller="MyController">
<ul>
<li class="Status" ng-repeat="item in myvar">
{{item.var}}
</li>
</ul>
<button ng-click="view()">View More</button>
2.I please suggest me
According to ng-repead documentation (check Tracking and Duplicates section) "track by $index" is what you need
<li class="Status" ng-repeat="item in myvar track by $index">
{{item.var}}
</li>
You can also use "track by yuor_primary_key".
You need to push new element every time in array
Check this code: http://codepen.io/anon/pen/bEwBwQ
Controller
angular.module('DemoApp', ['ui.router', 'ngAnimate'])
.controller('DemoController', function($scope, $window, $state) {
$scope.myvar = [{"var" : 1}];
$scope.save = function() {
//some ajax calll
var v = {"var" : 1};
$scope.myvar.push(v);
};
});
HTML
<ul>
<li class="Status" ng-repeat="item in myvar">
{{item.var}}
</li>
</ul>
<button ng-click="save()">save</button>
Given the following:
<div ng-app="interactive">
<main ng-controller="RecipesController">
<ul>
<li ng-repeat="option in options">
<ul decisionIndex="{{ value }}">
<li>Edit {{ option.name }}</li>
<li>Choose {{ option.name }}</li>
<li>Delete {{ option.name }}</li>
</ul>
</li>
</ul>
</main>
</div>
How can I use $watch to detect whether "value" (is either 0, 1 or 2) changes?
Do I need to use $watchGroup ? As far as I know that only works if you have multiple attributes which are not the same.
I found this working with directives and isolated scopes, but it does not quite match my case and I would prefer not using directives. Is it possible using isolated scopes without directives? Or how can I watch for changes of an attribute-value occuring multiple times?
EDIT:
This is how I tried using $watch
app.controller('RecipesController', ['$scope', function ($scope) {
$scope.$watch('value', function () {
console.log('value: ' + $scope.value);
});
}]);
<div ng-app="myApp" ng-controller="myCtrl">
<input type="text" ng-model="value">
<p>Current value is: {{value}}</p>
<ul>
<li ng-repeat="option in options">
<ul decisionIndex="{{value}}">
<li ng-click="setValue(0)">Edit {{option.name}}</li>
<li ng-click="setValue(1)">Choose {{option.name}}</li>
<li ng-click="setValue(2)">Delete {{option.name}}</li>
</ul>
</li>
</ul>
</div>
Controller:
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope) {
$scope.value = 0; //Set initial value, or just declare it;
$scope.options = [
{name: "Bob"},
];
$scope.setValue = function(a){
$scope.value = a;
}
$scope.$watch('value', function(newVal, oldVal){
console.log(newVal);
})
}]);
I'm trying to access the $parent in my child controller but for some reason I have to access the Fifth $parent in order to get the actual $scope from the Parent controller, Any Ideas?
Parent Controller
angular.module('App')
.controller('HomeController', ['$scope', '$rootScope', 'user',
function($scope, $rootScope, user) {
$rootScope.currentNav = 'home';
$rootScope.currentUser = user.data;
$scope.tabs = [
{
heading : 'Empresas',
template : 'home_companies_tab.html'
},
{
heading : 'Tickets',
template : 'home_tickets_tab.html'
}
];
$scope.companies = []
$scope.selectedCompanyIndex = undefined;
$scope.selectedCompany = undefined;
$scope.selectedTicketIndex = undefined;
$scope.selectedTicket = undefined;
}]);
Child Controller
angular.module('App')
.controller('HomeCompaniesTabController', ['$scope', 'Companies',
function($scope, Companies) {
$scope.loadCompanies = function () {
$scope.companies = Companies.query();
}
/**
* Init
*/
$scope.selectCompany = function (company, index) {
$scope.$parent.selectedCompanyIndex = index; //this doesnt work
$scope.$parent.$parent.$parent.$parent.$parent.selectedCompany = company; //this does, why?
console.log($scope);
}
if($scope.currentUser.security < 3) {
$scope.loadCompanies();
}
}]);
Home template
<div ng-include="'dist/templates/header.html'"></div>
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
company : {{selectedCompany}}
</div>
</div>
<tabset>
<tab ng-repeat="tab in tabs" heading="{{tab.heading}}">
<div ng-include="'dist/templates/' + tab.template" ></div>
</tab>
</tabset>
</div>
Child template
<div class="row-fluid" ng-controller="HomeCompaniesTabController">
<div class="col-md-3">
<h4>Lista de Empresas</h4>
<hr/>
<div class="list-group">
<a
href=""
class="list-group-item"
ng-repeat="company in companies"
ng-click="selectCompany(company, $index)">
<h4 class="list-group-item-heading">
{{company.name}}
</h4>
</a>
</div>
</div>
<div class="col-xs-9">
<div ng-show="selectedCompany">
<h4><b>{{selectedCompany.name}}</b></h4>
</div>
</div>
Based on the comments of charlietfl I came up with this simple service for sharing data
angular.module('App')
.factory('SharedData', [function () {
return {
}
}]);
Then I simply inject it in the controllers
angular.module('App')
.controller('HomeController', ['$scope', '$rootScope', 'user', 'SharedData',
function($scope, $rootScope, user, SharedData) {
$rootScope.currentNav = 'home';
$rootScope.currentUser = user.data;
$scope.sharedData = SharedData;
$scope.tabs = [
{
heading : 'Empresas',
template : 'home_companies_tab.html'
},
{
heading : 'Tickets',
template : 'home_tickets_tab.html'
}
];
$scope.companies = [];
}]);
I am new to angular js and the following code am using in my project here my problem is when i click on ng-click=addtocart(parameter) it is not responding the child controller.?how can i call the child controller ?please help me out?
<div ng-app="" ng-controller="parentCtrl">
<ul>
<li ng-click="search('12345');">
<div >
<div>
<div><img src="ProfileImges/menu.jpg"/></div>
<div>Hello</div>
</div>
</div>
</li>
</ul>
<div ng-repeat="x in names">
<div ng-click="addToCart('SMN1');">
<div>
<h4> {{ x.Price }} per meal</h4>
<img ng-src="{{x.ImgSrc}}"/>
</div>
<div>
<img ng-src="{{x.UserImg}}"/>
<p><strong>{{x.Uname}}</strong><br>
<span>{{x.RewPer}} </span><br>
</p>
</div>
<h4>{{x.Mtitle}}</h4>
<span><strong>{{x.Cuisine}}</strong></span>
<p`enter code here`>{{x.Mdesc}}</p>
</div>
</div>
<div ng-controller="childCtrl">
<div>{{cartdetails.name }}</div>
<div>Price</div>
</div>
</div>
<script>
var sj=angular.module('MyApp', []);
sj.controller('parentCtrl', ['$scope','$http', function($scope, $http) {
$scope.search = function(param) {alert("enter123");
$http.get('AngularJs-Response.jsp?mid='+param).success(function(response) {
$scope.names = response;
});
};
$scope.addToCart=function(smid){
CallAddCart(smid);
};
}]);
function CallAddCart(smid) {
sj.controller('childCtrl', ['$scope','$http', function($scope, $http) {
$http.get('reponse.jsp?smid='+smid).success(function(response) {alert(response);
$scope.cartdetails = response;
});
}]);
};
</script>
See plnkr: http://plnkr.co/edit/IdsHc19xBUalZoIXPE2T?p=preview
In a nutshell, you can communicate from parent to child controller by using the $scope as an event bus via the $broadcast and $on APIs:
angular.module("app", [])
.controller("ParentCtrl", function($scope) {
$scope.parentName = "parent";
$scope.onClick = function() {
$scope.parentName = "clicked";
$scope.$broadcast('onSearch', {myMsg: "hi children"});
}
})
.controller("ChildCtrl", function($scope) {
$scope.childName = "child";
$scope.$on('onSearch', function(event, obj) {
$scope.childName = obj.myMsg;
})
});
After onClick() is called on the parent, the parent $broadcasts the 'name' on the 'onSearch' channel to all its children. ChildCtrl is configured to listen on the 'onSearch' channel, once it receives a message, the callback function executes.