I'm trying to access my home controller scope from dashboard component but it's undefined.
I also tried a second approach but then my function variable is undefined.
I'm using Angular 1.5 with Typescript
FIRST APPROACH:
Home controller HTML:
<div class="home-container">
<dashboard-component on-tile-type-changed="HomeCtrl.onTileTypeChanged">
</dashboard-component>
</div>
Home controller js:
namespace app.dashboard {
'use strict';
class HomeController {
static $inject:Array<string> = ['$window'];
constructor(private $window:ng.IWindowService) {
}
private onTileTypeChanged(tile:ITile) {
console.log(tile); // DEFINED AND WORKING
console.log(this); // NOT DEFINED
}
}
angular
.module('app.dashboard')
.controller('HomeController', HomeController);
}
Dashboard controller js:
angular.module('app.dashboard')
.component('dashboardComponent', {
templateUrl: 'app/dashboard/directives/dashboard-container.html',
controller: DashboardComponent,
controllerAs: 'DashboardCtrl',
bindings: {
onTileTypeChanged: "&"
}
});
this.onTileTypeChanged()(tile);
SECOND APPROACH:
Home controller HTML:
<div class="home-container">
<dashboard-component on-tile-type-changed="HomeCtrl.onTileTypeChanged()">
</dashboard-component>
</div>
Dashboard controller js:
this.onTileTypeChanged(tile);
And here I'm getting the opposite:
private onTileTypeChanged(tile:ITile) {
console.log(tile); // NOT DEFINED
console.log(this); // DEFINED AND WORKING
}
You are using expression binding.
angular.module('app.dashboard')
.component('dashboardComponent', {
templateUrl: 'app/dashboard/directives/dashboard-container.html',
controller: DashboardComponent,
controllerAs: 'DashboardCtrl',
bindings: {
onTileChange: "&"
}
})t
To communicate event data from a component to a parent controller:
Instantiate the dashboard-component
with:
<dashboard-component on-tile-change="HomeCtrl.onTileChange($tile)">
</dashboard-component>
In the component controller invoke the function with locals:
this.onTileChange({$tile: tile});
The convention for injected locals is to name them with a $
prefix to differentiate them from variables on parent scope.
From the Docs:
&
or&attr
- provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given<my-component my-attr="count = count + value">
and the isolate scope definitionscope: { localFn:'&myAttr' }
, the isolate scope propertylocalFn
will point to a function wrapper for thecount = count + value
expression. Often it's desirable to pass data from the isolated scope via an expression to the parent scope. This can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression isincrement($amount)
then we can specify the amount value by calling thelocalFn
aslocalFn({$amount: 22})
.
-- AngularJS Comprehensive Directive API Reference
"&"
) binding to pass dataangular.module("app",[])
.directive("customDirective",function() {
return {
scope: {
onSave: '&',
},
template: `
<fieldset>
<input ng-model="message"><br>
<button ng-click="onSave({$event: message})">Save</button>
</fieldset>
`,
};
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<custom-directive on-save="message=$event">
</custom-directive>
<br>
message={{message}}
</body>