Angularjs parent scope use the child scope'attribute - javascript

angular.module('myApp',[])
.controller('Parent',['$scope',function($scope){
//define nothing
}]).controller('Child',['$scope',function($scope){
$scope.user={username:''};//define an object user
}])
<div ng-app="myApp">
<div ng-controller="Parent">
{{user}}<!--print nothing-->
<div ng-controller="Child">
{{user}} <!--print an object-->
</div>
</div>
</div>
How to deal with the problem above without using the inject of $rootScope

Based on your comment...
i want the parent user print the value of child user without using $rootScope
... you can't accomplish this because the parent scope cannot inherit from the child scope as it is currently defined. View controllers inherit from their parent controllers based on their node structure.
<parent-node>
{{user.name}}
<hr/>
<child-node>
<!-- user inherit from parent node's scope by default -->
{{user.email}}
</child-node>
<another-child-node>
<!-- user inherit from parent node's scope by default -->
{{user.someOtherData}}
</another-child-node>
You either need to define the user on your parent scope like so:
.controller('Parent',['$scope',function($scope){
$scope.user = {};
}])
.controller('Child',['$scope',function($scope){
}])
... or you can handle this via a directive depending on the end User-eXperience.

This is a problem that returns when people use $scope without reading up on the scopes documentation.
This is why I always tell people not to use $scope to bind objects / functions to. Well this and maintainability.
CONTROLLERS:
angular.module('myApp',[])
.controller('Parent',['$scope',function(){
//define nothing
}])
.controller('Child',['$scope',function(){
this.user = {username:''}; //define an object user
}]);
TEMPLATE:
<div ng-app="myApp">
<div ng-controller="Parent as parentCtrl">
{{ parentCtrl.user }} <!-- undefined -->
<div ng-controller="Child as childCtrl">
{{ childCtrl.user }} <!-- object -->
</div>
</div>
</div>

Related

The changes on $scope created by ng-repeat + ng-controller do affect the parent's $scope?

Let's say I have the following code:
<div ng-controller='Controller1'>
<div ng-repeat='item in things.list_itens' ng-controller='Controller2'>
</div>
</div>
If on Controller2's $scope, I change something that comes from Controller1 by the item on the ng-repeat, it will affect the parent scope value?
// Controller2
$scope.item = "other thing";
It will take effect on the $scope.things.list_itens[x] on Controller1?

How do I pass a variable from the parent scope to a child scope in AngularJS

I have a partial page with code similar to the following:
<div class="selector-result row">
<div ng-if="resultCtrl.result">
<div class="col-xs-12">
<h4><strong>We Recommend:</strong></h4>
<h2><strong>{{resultCtrl.result.Name}}</strong></h2>
</div>
<div class="row">
<div class="col-md-4">
<div ng-controller="selectorResultCarouselController">
<div>
<div style="height: 305px">
<carousel interval="myInterval" no-wrap="false">
<slide ng-repeat="slide in slides" active="slide.active" actual="slide">
<img ng-src="{{slide.image}}" style="margin:auto;">
</slide>
</carousel>
</div>
</div>
</div>
...
I have a module that has a directive (selectorResult) with a controllerAs resultCtrl. There is a controller in there too, selectorResultController, which loads a variable 'results'.
What I'd like to do is get {{resultCtrl.result.AllImages}} into selectorResultCarouselController somehow so that I can add them to my carousel. I'm lost. I'm trying really hard to understand Angular, and I think I understand how the pieces work, I just am not understanding the system, if that makes sense.
I'm just looking for a little nudge here. I've read and read and read, but I've not seen anything that is shining light on this problem.
To avoid $scope confusion, consider using AngularJS's controllerAs syntax. Basically, instead of attaching values to $scope, you attach them to the controller object itself. So:
angular.module('myApp', [])
.controller('ctrlOne', [function() {
var self = this;
self.name = 'ctrlOne';
}])
.controller('ctrlTwo', [function() {
var self = this;
self.name = 'ctrlTwo';
}]);
and
<div ng-app="myApp">
<div ng-controller="ctrlOne as one">
<div ng-controller="ctrlTwo as two">
<p>{{one.name}}</p> <!-- 'ctrlOne' -->
<p>{{two.name}}</p> <!-- 'ctrlTwo' -->
</div>
</div>
</div>
Child scope inherits from the parent. So just use $scope.result.AllImages.
A "child scope" (prototypically) inherits properties from its parent scope.
from: https://docs.angularjs.org/guide/scope.
In your case, in your child scope your variable is available as $scope.result.Allmages.
If your directive has an isolate scope, you will have to bind it through attributes in your directive definition object (ddo). The attributes &, #, and = will allow you to do this.
scope { myAttribute: '#', myOtherAttribute: '&', myLastAttribute: '='}
And in your directive you would use something like:
<my-directive my-attribute="someString" my-other-attribute="someCallbackOnControllerScope()" my-last-attribute="somePropertyOnControllerScopeYouWantToBindTwoWays">
Please note that if you use the '#', it will passed as a string and you will have to parse it against the parent scope to turn it into an object (in the directive's post-link function):
$parse(myAttribute)(scope.$parent)
Otherwise your ddo can have a scope property set to false, in which case it will use the parent scope.
If you have a scope property set to true in the ddo you can still address the parent scope property (by referencing it as if you had no child scope/as if it were in that same scope already available), though be careful if you do this (scope: true) and have multiple of the same directives... As they will all share the same scope and thus override each other.
Please check this page out for more information: AngularJS Documentation
I hope this was helpful

Angularjs:ng model is not accessible

I am using ng-template in angularjs
<script type="text/ng-template" id="ng-wig/views/ng-wig.html">
<div class="ng-wig">
........
</div>
<script>
and i have a textarea using this ng-template.
<textarea ng-wig="content" ng-model="contents"></textarea>
but this ng-model cannot be accessed inside the controller.
please help.
As you are loading your textarea template inside ng-include, if you look at ng-include directive you will see that it does create a new scope which is prototypically inherited from the parent scope.
If you use any scope variable which are declared in controller won't be accessible inside the include div. In order to get the controller variable accessible inside ng-include the you must declare it as object like $scope.model= {} then you should declare the properties in it. like ng-mode="model.contents"
Markup
<textarea ng-wig="model.content" ng-model="model.contents"></textarea>
Controller
$scope.model = {};
Here you can find similar answer
There are several approaches apart from above by which you could solve this issue.
The other way around would be, you could use controller as approach in that way you can avoid. In that you need to use this inside a controller & use controller alias while showing variable on html like vm.contents here
Makrup
<div ng-controller="myCtrl as vm">
<div ng-include="'ng-wig/views/ng-wig.html'"></div>
</div>
Textarea
<textarea ng-wig="content" ng-model="vm.contents"></textarea>
Also you could point to the parent scope of ng-include which is nothing but controller scope just by doing $parent in your ng-model, this case your ng-model would be $parent.contents
Textarea
<textarea ng-wig="$parent.content" ng-model="$parent.contents"></textarea>
Note
Don't use this approach, use the 1st one which is more preferable.

How to pass an item from ng-repeat to a controller created/loaded by ng-include?

I have an ng-repeat that loads an ng-include. I'd like to have a separate controller inside the view that the ng-include loads.
But I'm having trouble accessing the item from ng-repeat in that controller. I tried something like this, and it fails.
How do I get at result inside of SubController?
<div ng-repeat="result in results">
<div class="box" ng-include="view/someinclude.html"></div>
</div>
view/someinclude.html:
<div ng-controller="SubController">
...
</div>
controller js:
angular.module('SubController', [])
.controller('SubController', ['$scope',
function ($scope) {
//fails
console.log($scope.result);
}
]);
Make sure your scopes are a part of the same module, or they they're different include one in the other, if that's not the problem then it'll be something outside what you've shown, as something like this:
angular.module("app").controller.(testController", ["$scope", function($scope){
console.log($scope.x)
}])
with:
<div ng-repeat = "x in [1,2]">
<div ng-include = "'./views/vew.test.html'">
</div>
</div>
and in vew.test.html:
<div ng-controller = "testController">
{{x}}
</div>
Will wack 1 and 2 on the screen and in the console.
Make sure you're using the same module:
angular.module('SubController').controller('SubController', function() {...});
Try using $parent.result instead of $scope.result inside your controller as ng-include creates a new scope of its own that prototypically inherits from its parent scope.

Multiple ng-init scope issues

I'm trying to use ng-include with ng-init to re-use the same component by only changing its data.
The component code ("slider.html", which has no controller) looks like this:
<div ng-repeat="person in persons">
{{person.name}}
</div>
From the main view, I want to reuse the same component changing "persons" list so in the view I have:
<!--slider #1 -->
<div ng-init="persons=english" ng-include ="'inc/app/views/widgets/slider.html'"></div>
<!-- slider #2 -->
<div ng-init="persons=german" ng-include ="'inc/app/views/widgets/slider.html'"></div>
and in the controller I initialize the 2 lists "english" and "german" like this:
$scope.english = records.filter(function(t){return t.nationality=="english";});
$scope.german = records.filter(function(t){return t.nationality=="german";});
What happens is that the 2 components shows the same list of data (german); is there a way to bind the 2 different sets to the components?
That (having both lists being set as German) happens because, at the end, you are only using one controller, which has only one scope in which the persons varaiable exists. When AngularJS starts its bootstrapping process, it processes the first ng-init, updating the current controller's persons variable to English. Then it processes the second ng-init, updating again the same persons variable now to German. Then, when the ng-repeat is rendered, it will take the current and unique persons variable data, hence, being everything in German.
What you can do is to have an independent controller per component (slider.html), so each controller will have its own binding variables so you can create a persons variable for each one and initialize every controller's variable independently with your ng-init directive. Example:
<div ng-controller="MySubController" ng-repeat="person in persons">
{{person.name}}
</div>
...
<!--slider #1 -->
<div ng-init="initMySubController(english)" ng-include ="'inc/app/views/widgets/slider.html'"></div>
<!-- slider #2 -->
<div ng-init="initMySubController(german)" ng-include ="'inc/app/views/widgets/slider.html'"></div>
In a JS file:
var myApp = angular.module('myApp',[]);
myApp.controller('MySubController', ['$scope', function($scope) {
$scope.persons = [];
$scope.initMySubController = function(personsData) {
$scope.persons = personsData;
}
}]);

Categories