我跟着this post熟悉了Angular的1.5组件postLink事件。
我的工作是plunker。这是选项卡组件的代码:
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);
};
}
控制台输出:
然而,当我尝试在打字稿中做同样的事情时,postLink事件会很快被触发。在将选项卡添加到选项卡组件之前,它会被触发。
以下是一些代码: /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);
}
}
}
模板是一样的。
现在控制台输出是:
我在这里错过了什么吗?
答案 0 :(得分:1)
@ kuhnroyal的回答是正确的。但我想发布一个后续行动,因为它可能对其他有相同问题的人有用。我已经找到了一个解决方案,它允许我在单独的文件中使用模板(这提高了可维护性),但仍然使用template-property来保证postLink事件的正确顺序。
我现在使用角度$templateCache
对象。关键是在角度应用程序启动时预加载所有模板。然后使用$templateCache.get
方法填充组件上的template-property。这post引导我解决这个问题。
答案 1 :(得分:0)
嗯,你现在正在使用不同的方法。在您将其推入一个控制器中的数组之前。现在你有两个组件和控制器。
从Typescript文档中,这是你的问题。
/** * Called after this controller's element and its children have been linked. Similar to the post-link function this * hook can be used to set up DOM event handlers and do direct DOM manipulation. Note that child elements that contain * templateUrl directives will not have been compiled and linked since they are waiting for their template to load * asynchronously and their own compilation and linking has been suspended until that occurs. This hook can be considered * analogous to the ngAfterViewInit and ngAfterContentInit hooks in Angular 2. Since the compilation process is rather * different in Angular 1 there is no direct mapping and care should be taken when upgrading. */ $postLink?(): void;
请注意,包含templateUrl指令的子元素不会 已经编译和链接,因为他们正在等待他们的 模板加载异步和自己的编译和链接 已经暂停,直到发生。
您应该将require
数组绑定到子节点上,而不是使用tabs
。