0

Im begginer with Angular.js, so if I dont explain something enought, I will add it to question, just tell me.

I have: A component.js A template.html B component.js B template.html.

A component.js has $scope.isActive = true, and code changes value as needed. This attribute works in template A template.html.

Problem is, that I want to use same value, for B template.html. I have no idea how to pass it, I have also B component.js working with B template.html, if this matters somehow.

Right now Im trying to use $scope.isActive from A component.js in B template.html, but it does nothing, I guess it comes undefined.

This is how I try to use it in B template.html

<img src="res/large-loading.gif" ng-if="!isActive">
    

1 Answer 1

1

The best solution is to move $scope.isActive to a new 'root' component that contains both 'component A' and 'component B'. Then you can pass / modify its value using input/output bindings in the 'component A' and 'component B' definitions like:

component A definition:

angular.module('app').component('componentA', {    
    templateUrl: 'component-A.html',                 
    bindings: {
       isActive: "<", // use to bind property as component input
       isActiveChanged: "&" // use to bind a METHOD that changes the property in the root component controller
    }
});

component A template (component-A.html):

<img 
   src="res/large-loading.gif" 
   ng-if="!$ctrl.isActive" 
   ng-click="$ctrl.isActiveChanged({isActive: !$ctrl.isActive})"/>

component B definition:

angular.module('app').component('componentB', {    
    template: 'component-B.html',                 
    bindings: {
       isActive: "<", // use to bind property as component input
       isActiveChanged: "&" // use to bind a METHOD that changes the property in the root component controller
    }
});

component B template (component-B.html):

<img 
   src="res/large-loading.gif" 
   ng-if="!$ctrl.isActive" 
   ng-click="$ctrl.isActiveChanged({isActive: !$ctrl.isActive})"/>

root component definition:

angular.module('app').component('root', {    
    templateUrl: 'root-component-view.html', ,                 
    controller: 'RootComponentCtrl'
});

root component controller:

angular.module('app').controller('RootComponentCtrl', ['$scope', function($scope) {
   // INPUT: This property is shared with both 'component A' and 'component B'
   $scope.isActive = true; 
   // OUTPUT: This method is shared with both 'component A' and 'component B' and can be called from both in order to change the value of $scope.isActive in the RootComponentCtrl
   $scope.isActiveChanged(isActive) {
      $scope.isActive = isActive;
   };
}]);

root-component-view.html template:

<div>
   <component-a 
      is-active="isActive" 
      is-active-changed="isActiveChanged(isActive)"
   ></component-a>
   <component-b 
      is-active="isActive" 
      is-active-changed="isActiveChanged(isActive)"
   ></component-b>
</div>

Notice that binded properties are accessed in the component view/template using the '$ctrl' object like '$ctrl.isActive' as opposed to simply using 'isActive' which refers to the component's $scope.isActive property in the component controller.

To resume: The shared property is set in the root component controller using:

$scope.isActive = true;

The shared property can be seen in the root component template using:

...>some html text content plus this is {{isActive}}<...

The shared property is passed to componentA and componentB in the html that defines them in the root component view using:

<component-a 
      is-active="isActive" 
      is-active-changed="isActiveChanged(isActive)"
   ></component-a>
   <component-b 
      is-active="isActive" 
      is-active-changed="isActiveChanged(isActive)"
   ></component-b>

The shared property is visible in componentA / componentB templates using:

...>some html text content plus this is {{$ctrl.isActive}}<...

The shared property is visible in componentA / componentB controllers using:

   this.isActive // not $scope.isActive

The shared property can be changed from componentA / componentB controllers by calling the method:

$ctrl.isActiveChanged({data: data})

Which actually will call the method in the root component controller and pass the updated value to the $scope property:

$scope.isActiveChanged(data)
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.