I followed this post to get acquainted with Angular's 1.5 component postLink event.
I got this working in a plunker. Here's the code for the tabs component:
controller: function () {
this.$onInit = function () {
console.log("$onInit");
this.tabs = [];
};
this.addTab = function addTab(tab) {
console.log("addTab");
this.tabs.push(tab);
};
this.selectTab = function selectTab(index) {
for (var i = 0; i < this.tabs.length; i++) {
this.tabs[i].selected = false;
}
this.tabs[index].selected = true;
};
this.$postLink = function () {
console.log("$postLink. nr of tabs added: " + this.tabs.length);
this.selectTab(this.selected);
};
}
The console output:
- $onInit
- addTab
- addTab
- addTab
- $postLink. nr of tabs added: 3
However, when I try to do the same in typescript, the postLink event gets triggered too soon. It gets triggered before the tabs can be added to the tabs-component.
Here's some of the code: /tabs/tab/tab.component.ts
namespace MainApp {
const mainApp = angular.module("mainApp");
class TabComponent implements ng.IComponentOptions {
public templateUrl: string | ng.Injectable<(...args: any[]) => string>;
public controller: any;
public controllerAs: string;
public transclude: boolean;
public bindings: any;
public require: any;
constructor() {
this.templateUrl = ["rootUrl", (rootUrl) => rootUrl + "app/uitrijregelingBerekening/tabs/tab/tab.html"];
this.controller = TabController;
this.transclude = true;
this.bindings = {
label: "@",
};
this.require = {
tabs: "^^",
};
}
}
mainApp.component("tab", new TabComponent());
}
/tabs/tab/tab.controller.ts
namespace MainApp {
interface ITabBindings {
label: string;
}
export class TabController implements ITabBindings {
public label: string;
private tabs: TabsController;
public tab: any;
constructor() {
}
public $onInit() {
this.tab = {
label: this.label,
selected: false
};
this.tabs.addTab(this.tab);
}
}
}
/tabs/tabs.component.ts
namespace MainApp {
const mainApp = angular.module("mainApp");
class TabsComponent implements ng.IComponentOptions{
public templateUrl: string | ng.Injectable<(...args: any[]) => string>;
public controller: any;
public controllerAs: string;
public bindings: any;
public transclude: boolean;
constructor() {
this.templateUrl = ["rootUrl", (rootUrl) => rootUrl + "app/uitrijregelingBerekening/tabs/tabs.html"];
this.controller = TabsController;
this.bindings = {
selected:"@",
};
this.transclude = true;
}
}
mainApp.component("tabs", new TabsComponent());
}
/tabs/tabs.controller.ts
namespace MainApp {
export interface ITabsBindings {
selected: number;
}
export class TabsController implements ITabsBindings {
public selected: number;
public tabs: Array<any>;
private scope: any;
static $inject = ["$scope"];
constructor($scope: ng.IScope) {
this.scope = $scope;
}
public $onInit() {
console.log("$onInit");
this.tabs = new Array<any>();
}
public addTab(tab: any) {
console.log("addTab");
this.tabs.push(tab);
}
public selectTab(index: number) {
for (var i = 0; i < this.tabs.length; i++) {
this.tabs[i].selected = false;
}
this.tabs[index].selected = true;
}
public $postLink() {
console.log("$postLink. nr of tabs added: " + this.tabs.length);
this.selectTab(this.selected);
}
}
}
The templates are the same.
Now the console output is:
- $onInit
- $postLink. nr of tabs added: 0
- angular.js:13920 TypeError: Cannot set property 'selected' of undefined
- addTab
- addTab
- addTab
Am I missing something here?