Here are 3 ways to share data or functions across components :
The bad one :
Use <
and =
bindings to share functions between component is possible but very ugly and should be avoided.
Here is an example :
HTML
<script id="header-template" type="text/ng-template">
<h1>HEADER</h1>
<button type="button" ng-click="model.selectAll()" class="btn btn-sm btn-default">Select All</button>
<button type="button" ng-click="model.deselectAll()" class="btn btn-sm btn-default">Deselect All</button>
<br />
<br />
<hr />
</script>
<script id="content-template" type="text/ng-template">
<h2>Content</h2>
<button type="button" ng-click="model.selectAll()" class="btn btn-sm btn-default">Select All</button>
<button type="button" ng-click="model.deselectAll()" class="btn btn-sm btn-default">Deselect All</button>
<br />
<br />
<div class="item_container" multiple-selection-zone>
<div ng-repeat="f in model.transaction.fields" multiple-selection-item class="well" ng-class="{'selecting': isSelecting ,'selected': isSelected || model.isSelected}">{{f.label}}</div>
</div>
<br />
<br />
</script>
JS
function parentController(TransactionFactory) {
var model = this;
model.transaction = TransactionFactory;
model.selectAll = null;
model.deselectAll = null;
}
function headerController(TransactionFactory) {
var model = this;
model.transaction = TransactionFactory;
}
function contentController(TransactionFactory) {
var model = this;
model.transaction = TransactionFactory;
model.selectAll = function() {
//mark all fields as selected
model.isSelected = true;
}
model.deselectAll = function() {
//deselect all fields that are selected
model.isSelected = false;
}
this.$onInit = function() {
model.cSelectAll = model.selectAll;
model.cDeselectAll = model.deselectAll;
}
}
var app = angular.module("app", ['multipleSelection']);
app.factory('TransactionFactory', function () {
var transaction = {
fields: [
{label: "field 1"},
{label: "field 2"},
{label: "field 3"},
{label: "field 4"},
{label: "field 5"}]
};
return transaction;
});
app.component("parentComponent", {
template: $("#parent-template").html(),
controllerAs: "model",
controller: ["TransactionFactory", parentController]
});
app.component("headerComponent", {
template: $("#header-template").html(),
controllerAs: "model",
controller: ["TransactionFactory", headerController],
bindings: {
selectAll: '<',
deselectAll: '<',
}
});
app.component("contentComponent", {
template: $("#content-template").html(),
controllerAs: "model",
controller: ["TransactionFactory", contentController],
bindings: {
cSelectAll: '=',
cDeselectAll: '=',
}
});
The plunker.
The correct one
HTML
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
<link rel="stylesheet" href="style.css" />
<script id="header-template" type="text/ng-template">
<h1>HEADER</h1>
<button type="button" ng-click="model.makeRed()">Make Red</button>
<button type="button" ng-click="model.makeBlue()">Make Blue</button>
<br />
<br />
<pre>{{model}}</pre>
<hr />
</script>
<script id="content-template" type="text/ng-template">
<h2>Content</h2>
<div ng-class="model.colorMe">Object to color</div>
<br />
<br />
<br />
<pre>{{model}}</pre>
</script>
<script id="root-template" type="text/ng-template">
<header-component color-me="model.colorme" make-red="model.makeRed()" make-blue="model.makeBlue()"></header-component>
<content-component color-me="model.colorme" make-red="model.makeRed()" make-blue="model.makeBlue()"></content-component>
</script>
<script src="script.js"></script>
</head>
<body>
<div class="container">
<root-component></root-component>
</div>
</body>
</html>
JS
console.clear();
function headerController() {
var model = this;
model.test = "test header";
console.log(model);
}
function contentController() {
var model = this;
model.test = "test content";
model.makeBlue();
console.log(model);
}
function rootController() {
var model = this;
model.makeRed = function() {
console.log('red');
model.colorme = "red";
}
model.makeBlue = function() {
console.log('blue');
model.colorme = "blue";
}
console.log(model);
}
var app = angular.module("app", []);
app.component("rootComponent", {
template: $("#root-template").html(),
controllerAs: "model",
controller: [rootController]
});
app.component("headerComponent", {
template: $("#header-template").html(),
controllerAs: "model",
controller: [headerController],
bindings: {
makeRed: '&',
makeBlue: '&',
colorMe: '<',
}
});
app.component("contentComponent", {
template: $("#content-template").html(),
controllerAs: "model",
controller: [contentController],
bindings: {
makeRed: '&',
makeBlue: '&',
colorMe: '<',
}
});
your plunker
With bindings you can share variable (colorMe) with <
binding or functions (makeBlue and makeRed) with &
binding accross components with the same parent.
The perfect one
You can use a angular.service to store and modify the state and share it between components.