Given following common setup:
CtrlA (page level controller)
|- directiveAA (component e.g. button bar)
|- directiveAAA (sub-component e.g. button)
I would like to call CtrlA.methodA() from directiveAAA by passing the methodA down the chain using directive attributes - CtrlA -> directiveAA -> directiveAAA
. So for example my directiveAAA
"Save" button can call controller method "Save". Components directiveAA
and directiveAAA
are dumb components and only know about their environment given their attribute settings.
Before Typescript I would make use of inherited scope down the chain to call controller method $scope.save()
from directiveAAA
.
How would this work with Typescript? Would we still have to make use of injected scope into our controller, directive controller classes or can this be done without using scope, based on class inheritance?
So here's my question in code - its probably not perfect but gives the gist - the nub of the problem is marked with comment "this is where i need help":
module app.page {
class CtrlPage {
private ctrlPageBtnActions: string[] = ['goPrev', 'goNext'];
goPrev(){
console.log('go previous');
}
goNext(){
console.log('go next');
}
}
function pageDirective(){
return {
restrict: 'E',
replace: true,
template: '<button-bar actions="CtrlPage.ctrlPageActions"></button-bar>',
controller: CtrlPage,
controllerAs: 'ctrlPage',
bindToController: true
}
}
angular.module('app')
.directive('page', pageDirective);
}
module app.page.directives {
class CtrlBtnBar {
private actions: string[];
}
function buttonBar() {
return {
restrict: 'E',
replace: true,
template: '<div class="buttonBar"><btn action="CtrlBtnBar.actions[0]"></btn><btn action="CtrlBtnBar.actions[1]"></btn></div>'
controller: CtrlBtnBar,
controllerAs: 'CtrlBtnBar',
bindToController: {
actions: '='
}
}
}
angular.module('app')
.directive('buttonBar', buttonBar);
}
module app.page.directives {
class CtrlBtn {
private action: string;
handleClick(){
if (action === 'goNext'){
CtrlPage.goNext(); /// Here is where I need help
}
}
}
function btnDirective(){
return {
restrict: 'E',
replace: true,
template: '<input type="button" value="someCaption" ng-click="CtrlBtn.handleClick()"/>',
controller: CtrlBtn,
controllerAs: 'ctrlBtn',
bindToController: {
action: '@'
}
}
}
angular.module('app')
.directíve('btn', btnDirective);
}
If you run the code in http://www.typescriptlang.org/Playground you will see that typescript understandably objects to CtrlPage reference from within btnDirective controller CtrlBtn, because within this context CtrlPage does not exist. Must we use angular $scope to access the "goNext" method, given that the btnDirective is dumb and is not aware of its parents controllers and only receives inputs from its attributes? Taking radim's tip into consideration I guess the answer is yes.