AngularJS $scope.$parent strange hierarchy - angularjs

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 = [];
}]);

Related

Get data from directive and change image according to data value

I want to get the value of current.flag from my template property in random.js file and use it after in my HTML file. According to the value of flag I will receive, I would like an image to be changed. I would like some help for that, because I'm beginner to Angular.
Thanks in advance
<section class="has-header">
<div class="container">
<div class="row">
<div class="col-md-4 text-center">
<img ng-src="{{current.flag === 'gr' ? 'images/image_1.png' : 'images/image_2.png'}}" />
</div>
</div>
</div>
</section>
random.js
angular.module('app')
.directive('language', function () {
return {
restrict: 'E',
replace: true,
scope: {},
template: '<div class="languages-wrap pull-right">\
<div class="languages f32">\
<div ng-click="poped=!poped" class="current flag {{current.flag}}"></div></div>\
<div class="language-selector" ng-show="poped">\
<ul class="languages-list">\
<li ng-repeat="l in langs">\
<a ng-click="changeLang(l)" class="languages f32">\
<div class="flag {{l.flag}}"></div>\
</a>\
</li>\
</ul>\
</div>\
</div>',
controller: ['$scope', '$cookies', '$translate', '$route', '$location',
function ($scope, $cookies, $translate, $route, $location) {
$scope.poped = false;
$scope.langs = [
{
iso: 'el',
flag: 'gr'
},
{
iso: 'en',
flag: 'us'
}
];
$scope.current = $cookies.getObject('lang') ? $cookies.getObject('lang') : $scope.langs[0];
$scope.changeLang = function (lang) {
$cookies.putObject('lang', lang, {expires: new Date(2020, 10, 10)});
$translate.use(lang.iso);
$scope.current = lang;
$scope.poped = false;
$location.search('lang', lang.iso);
$route.reload();
};
}
]
};
});
u can do a controller to the html file and add
$scope.current = $cookies.getObject('lang') ? $cookies.getObject('lang') : $scope.langs[0];
to the controller
if i understand correctly , u want to use the $scope.current value from a directive in another html file, which is not connected to the directive , if yes , what u can do is add a controller to this html and add the
$scope.current = $cookies.getObject('lang') ? $cookies.getObject('lang') : $scope.langs[0];
to it How to bind an AngularJS controller to dynamically added HTML?
make controller file
add it to index.html,
add this inside it
var app = angular.module('myApp', []);
app.controller('exampleCtrl', function($scope, $cookies) {
$scope.current = $cookies.getObject('lang') ? $cookies.getObject('lang') : $scope.langs[0];
});
in the html add controller to the section tag
<section class="has-header" ng-controller="exampleCtrl">

updating value in $scope in a sub state not working angularjs

I have a parent state which shows the list of apartments, on clicking any apartment a sub state is loaded which shows all the images for it. But value of $scope is not passing to ng-repeat. What possible mistake i have made here.
app.js :
state('projects', {
url: '/projects',
templateUrl : 'resources/partials/projectsNew.html',
controller : 'ProjectsController'
}).state('projects.project', {
url: '/project/:param',
templateUrl : 'resources/partials/projectImages.html',
controller : 'ProjectController'
})
Controllers :
decorpotCtrls.controller('ProjectsController', [ '$scope', 'cart', 'projects', '$rootScope',
function($scope, cart, projects, $rootScope) {
projects.getAllProjects().success(function(data) {
for (var i = 0; i < data.length; i++) {
data[i].APARTMENT = data[i].APARTMENT.replace(/\s+/g, '-');
}
$scope.projects = data;
});
} ]);
decorpotCtrls.controller('ProjectController', [
'$scope',
'cart',
'projects',
'$stateParams',
'$rootScope',
function($scope, cart, projects, $stateParams, $rootScope) {
var project = $stateParams.param;
projects.getImagesByAppartment(project).success(function(data) {
$scope.images = data;
console.log($scope.images);
});
} ]);
html :
ProjectsNew.html :-
<div class="pastProjects" ui-view>
<div class="col-md-3 .col-xs-12 .col-sm-6 imgContainerOuter"
ng-repeat="project in projects | filter:query">
<div class="imgContainer">
<a class="shrink"ui-sref="projects.project({param : '{{project.APARTMENT}}'})">
<img src={{project.SMALL_PATH}}>
</a>
</div>
<div class="textProjects">
<h4>{{project.APARTMENT}}</h4>
<span>Bangalore</span>
</div>
</div>
projectImages.html :-
<div id="gallery">
<a href="{{image.HD_PATH}}" ng-repeat="image in images | filter:query">
<img src="{{image.SMALL_PATH}}" alt="Photo 1" /></a>
</div>
when i am navigating from parent state projects to project ng-repeat doesnt works. I put a console log in ProjectController for the value of images its being populated correctly.

How do we call the child controller when parent controller ng-click directive called?

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.

Why won't my view template bind to a scope variable with AngularJS?

My view is:
<div class="container" ng-controller="MyController">
<div class="row">
<div class="col-md-8">
<textarea class="form-control" rows="10" ng-model="myWords" ng-change="parseLanguage()"></textarea>
</div>
<div class="col-md-4" ng-show="sourceLanguage !== null">
Language: {{ sourceLanguage }}
</div>
</div>
</div>
My controller is:
webApp.controller('MyController', [
'$scope', '$rootScope', 'TranslateService', function($scope, $rootScope, CodeService) {
$scope.init = function() {
return $scope.sourceLanguage = null;
};
$scope.parseLanguage = function() {
return TranslateService.detectLanguage($scope.myWords).then(function(response) {
console.log($scope.sourceLanguage);
$scope.sourceLanguage = response.data.sourceLanguage;
return console.log($scope.sourceLanguage);
});
};
return $scope.init();
}
]);
The console logs show the right data. But in the view, sourceLanguage never updates. Why would this be?
In case the promise you are evaluating is not part of the Angular context you need to use $scope.$apply:
$scope.parseLanguage = function() {
TranslateService.detectLanguage($scope.myWords).then(function(response) {
$scope.$apply(function() {
$scope.sourceLanguage = response.data.sourceLanguage;
});
});
};

Whats the solution here? want to re-use the same controller with different data

I have a grid like this
<div ng-controller="UserCtrl">
...
<div class="grid">
<div class="grid-header">
<h3>Showing {{users.records}} Users</h3>
</div>
<div class="grid-con">
<div class="grid-con-header row">
<div ng-click="sortOrder($event, 'fullName')" class="col-xs-4 sortable"><span>Name</span></div>
<div ng-click="sortOrder($event, 'emailAddress')" class="col-xs-4 sortable"><span>Email</span></div>
<div class="col-xs-4"></div>
</div>
<div class="grid-con-body">
<div ng-hide="isGridLoading" class="row" ng-repeat="row in users.rows">
<div class="col-xs-2">
{{row.fullName}}
</div>
<div class="col-xs-3">{{row.emailAddress}}</div>
<div class="col-xs-3">
<a ng-href="#/users/modify/{{row.loginId}}" type="button" class="btn btn-success">Modify</a>
</div>
</div>
<div class="row ajax-ngview" ng-show="isGridLoading"></div>
</div>
</div>
</div>
</div>
Here is my UserCtrl
function UsersCtrl($scope, Users) {
$scope.grid = {
"_search": '',
"page": 1,
"rows": 10,
"sidx": "loginId",
"sord": "asc"
};
$scope.users = {};
updateGrid();
function updateGrid() {
$scope.isGridLoading = true;
Users.get($scope.grid).$promise.then(function(result) {
$scope.users = result;
$scope.isGridLoading = false;
}, function(reason) {
});
}
$scope.sortOrder = function(event, name) {
...
}
}
I want to show this type of grid on multiple pages, I am not sure what best solution is here. Do I need to copy the UserCtrl and paste it as some like GroupCtrol and modify it as required or is there some better solution?
You could use $routeProvider's resolve property, to pass the appropriate model as a dependency:
/* First "generify" the controller */
angular.module('myApp').controller('gridCtrl', function ($scope, Data) {
$scope.grid = {
"_search": '',
"page": 1,
"rows": 10,
"sidx": "loginId",
"sord": "asc"
};
$scope.data = {};
updateGrid();
function updateGrid() {
$scope.isGridLoading = true;
Data.get($scope.grid).$promise.then(function (result) {
$scope.data = result;
$scope.isGridLoading = false;
}, function (reason) {...});
}
...
/* Second, configure $routeProvider to pass
* the appropriate model to each view */
angular.module('myApp').config(function ($routeProvider) {
$routeProvider
.when('/users', {
templateUrl: 'grid.html',
controller: 'gridCtrl',
resolve: {
Data: 'Users'
}
})
.when('/groups', {
templateUrl: 'grid.html',
controller: 'gridCtrl',
resolve: {
Data: 'Groups'
}
});
So, in the 1st case the Users service will be passed as a dependency to the gridCtrl controller (under the name of Data), whereas in the 2nd case the Groups service will be passed (again under the name of Data).
For what it's worth, I too do believe a directive would be more appropriate here...

Resources