Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Command a specific child component from parent in AngularJS

I'm using AngularJS 1.5.8. I have "myParent" and "myChild" components. In my view, i've 1 parent and 2 children inside that parent. So my question is: I wanna have instances of children "myChild" components in "myParent" component's controller, and give a command to only a specific child to makePrimary(), or like that... How can i achive this goal?

JS:

//var myApp = 
angular.module('myApp', ['myChild', 'myParent']);

angular.
module('myChild', []).
component('myChild', {
  template: '<div class="panel panel-default">' +
    '<div class="panel-heading">Child</div>' +
    '<div class="panel-body">' +
    'Child content...' +
    '</div>' +
    '</div>',
  controller: ['$scope', '$element',
    function myChildController($scope, $element) {

    }
  ]
});

angular.
module('myParent', ['myChild']).
component('myParent', {
  template: '<div class="panel panel-default">' +
    '<div class="panel-heading">Parent</div>' +
    '<div class="panel-body">' +
    '<my-child></my-child>' +
    '<hr />' +
    '<my-child></my-child>' +
    '</div>' +
    '</div>',
  controller: ['$scope', '$element',
    function myParentController($scope, $element) {

    // TODO: MAKE CHILD-2 ".panel-primary" CLASS IN HERE.
    // BUT ONLY A SPECIFIC CHILD!

    }
  ]
});

HTML:

<div ng-app="myApp" class="container">
  <my-parent></my-parent>
</div>

JSFIDDLE for sample: https://jsfiddle.net/zhc12t1a/4/

I inspected some related questions like:

  • angularJS: How to call child scope function in parent scope
  • AngularJS - Access to child scope

But i can't find a proper way to achive this goal with a simple architecture.

EDIT

I know some complicated methods (from architectural perspective) but i don't want to use them. For example:

Using $parent or

in myParentController:

$scope.makeChild1Primary = function () {} 

in myParent template:

<my-child make-primary="makeChild1Primary"></my-child>

in myChild component

//...
var ctrl = this;
ctrl.makePrimary = function () { /* MAKE PRIMARY LOGIC HERE... */ }
//...
,bindings: {
makePrimary: '='
}
like image 395
Burak TARHANLI Avatar asked Dec 04 '16 12:12

Burak TARHANLI


2 Answers

As mentioned in "AngularJS - Access to child scope", there is no way to access the childs scope from the parent, because AngularJS processes properties from child to parent, not the other way round.

If you don't want to bind the ng-class of the child element to a parent's property or use a common service, you have to explicitely add the childrens scopes to a parent property like so:

function myParentController($scope, $element) {
    $scope.children = [];
    ...
}

function myChildController($scope, $element) {
    $scope.$parent.children.push($scope);
}

Then you can access all children from the parent like so:

$scope.children[1].isPrimary = true;

While in your HTML you bind the class of the panel to the property "isPrimary" like so:

<div class="panel panel-default" ng-class="isPrimary ? 'panel-primary' : ''">

You can find the entire implementation of your example here: https://jsfiddle.net/81eesouy/7/

like image 146
ggradnig Avatar answered Sep 30 '22 07:09

ggradnig


Either use $emit or $broadcast event.

This is the best clean answer I think, you can try with services but this is the answer I like more :)

Fast example

function controllerParent($scope){
    $scope.emitActionClick = function(){
       $scope.$broadcast('myTestEvent',{data:"passed"})               
    }


}
function controllerChildX($scope){
   $scope.$on('myTestEvent',function(event,data){ 
      // HERE WE ARE :)
       console.log(data);
   }

}

If you are using Controller As You will need to inject $scope or $rootScope. There is no other way in handling emit and broadcast events unfortunately.

like image 21
Gosu Przmak Avatar answered Sep 30 '22 07:09

Gosu Przmak