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">
CodePudding user response:
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)