Reputation: 4245
I would like to create a left hand menu component which displays different menu structure depending on the string it gets via binding.
For example:
<left-hand-menu-component module='abc'></left-hand-menu-component>
Then it shows only the abc module's menu structure. In order to achieve that the component controller must be able to work with the data comes trough bindings and make the necessary service calls.
I have been googling around for a while how to achieve this and I have find this and this posts and this posts. The example available at Angular documentation is too simple.
I have put together the example's code above and that part is missing when the controller can work with the value coming trough bindings.
It is even possible? Or it is rather a directive than a component?
Do you know example where it is displayed, blog entry or any source?
The two console.log in the controller constructor write out 'undefined' as result.
Component:
module qa.gonogo {
"use strict";
export class LeftHandMenuComponent implements ng.IComponentOptions {
public transclude: boolean = false;
public controller: Function = LeftHandMenuComponentController;
public controllerAs: string = "vm";
public templateUrl: string = "app/content/lefthandmenu/leftHandMenuComponentTemplate.html";
public bindings: any;
constructor() {
this.bindings = {
module: '<'
}
}
}
angular
.module("goNoGo")
.component("gonogoLefthandmenuComponent", new LeftHandMenuComponent());
}
Controller:
export class LeftHandMenuComponentController implements ILeftHandMenuComponentController {
menuStructure: IMenuStructure[];
closeOthers: boolean = true;
static $inject = [];
constructor(public module: string) {
console.log('binding', module);
console.log('binding2', this.module);
}
public $onInit = (): void => {
this.populateMenuStructure();
}
Route.
$stateProvider
.state("bfts",
<ng.ui.IState>{
url: "/bfts",
views: <any>{
"leftHandMenu": <ng.ui.IState>{
template: "<gonogo-lefthandmenu-component module='bfts'></gonogo-lefthandmenu-component>"
},
"content": <ng.ui.IState>{
template: "bfts content"
}
}
});
Upvotes: 2
Views: 3237
Reputation: 353
The bindings are available in the controller scope, so this.module must work.
I reproduced your code in a plnkr and found following errors.
The main problem is that you use a "<" binding, which is a one-way binding. So it tries to access the "btfs" variable which is not defined in your scope, therefore undefined is absolutely correct output. To use a string use "@" see https://docs.angularjs.org/guide/component
constructor() { this.bindings = { module: '@' } }
dont inject the module var. just define it in your controller to satisfy typescript compiler.
public module: string;
you dont need controllerAs. The templates automatically gets the scope injected via $ctrl, see my example at medium. but not sure if thats critical
as I described in my post its always a good idea to put angular.module calls at the bottom of the source file
modified code:
angular.module('goNoGo', []);
class LeftHandMenuComponent implements ng.IComponentOptions {
public transclude: boolean = false;
public controller: Function = LeftHandMenuComponentController;
//public controllerAs: string = "vm";
public template: string = "<div>module :{{$ctrl.module}}</div>";
public bindings: any;
constructor() {
this.bindings = {
module: '@'
}
}
}
class LeftHandMenuComponentController {
menuStructure: IMenuStructure[];
closeOthers: boolean = true;
public module: string;
static $inject = [];
constructor() {
console.log('binding2', this.module);
}
//public $onInit = (): void => {
// this.populateMenuStructure();
}
angular
.module("goNoGo")
.component("gonogoLefthandmenuComponent", new LeftHandMenuComponent());
angular.element(document).ready(function () {
angular.bootstrap(document, ['goNoGo']);
});
you can play around in plnkr http://plnkr.co/edit/TVI9l8
Upvotes: 2