Angularjs Angular 1.5组件$postLink在中使用templateUrl时过早触发
我随后了解了Angular的1.5组件postLink事件 我是在一家公司工作的。以下是选项卡组件的代码:Angularjs Angular 1.5组件$postLink在中使用templateUrl时过早触发,angularjs,components,lifecycle,Angularjs,Components,Lifecycle,我随后了解了Angular的1.5组件postLink事件 我是在一家公司工作的。以下是选项卡组件的代码: controller: function () { this.$onInit = function () { console.log("$onInit"); this.tabs = []; }; this.addTab = function addTab(tab) { console.log("addTab"); this.tabs.push(tab); }; this.s
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);
};
}
/tabs/tabs.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());
}
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());
}
namespace MainApp{
常量mainApp=角度模块(“mainApp”);
类TabsComponent实现ng.IComponentOptions{
公共模板URL:string | ng.Injectable string>;
公共控制人:任何;
公共控制器:字符串;
公共约束:任何;
公共转置:布尔;
构造函数(){
this.templateUrl=[“rootUrl”,(rootUrl)=>rootUrl+“app/uitrijregelingBerekening/tabs/tabs.html”];
this.controller=选项卡控制器;
此文件的绑定={
已选定:“@”,
};
this.transclude=true;
}
}
mainApp.component(“制表符”,新制表符component());
}
/tabs/tabs.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);
}
}
}
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);
}
}
}
namespace MainApp{
导出接口ITabsBindings{
选定:编号;
}
导出类TabsController实现ITabsBindings{
公众选择:数字;
公共选项卡:数组;
私人范围:任何;
静态$inject=[“$scope”];
构造函数($scope:ng.IScope){
this.scope=$scope;
}
公共$onInit(){
console.log(“$onInit”);
this.tabs=新数组();
}
公共添加选项卡(选项卡:任意){
console.log(“addTab”);
这个.tabs.push(tab);
}
公共选择选项卡(索引:编号){
对于(var i=0;i
模板是相同的
现在控制台输出为:
- $onInit
- $postLink。已添加标签数量:0
- angular.js:13920 TypeError:无法设置未定义的属性“selected”
- 地址表
- 地址表
- 地址表
我在这里遗漏了什么吗?好吧,您现在使用的是不同的方法。在您将其推入一个控制器中的阵列之前。现在您有了两个组件和控制器 从Typescript文档来看,这是您的问题 请注意,包含templateUrl指令的子元素不会 已编译并链接,因为它们正在等待 异步加载的模板及其自己的编译和链接 已暂停,直到发生此情况。
与其使用
require
,不如将选项卡
数组绑定到子项。@kuhnroyal的答案在这里是正确的。但我想发布一篇后续文章,因为它可能对其他有同样问题的人有用。我已经找到了一个解决方案,允许我在单独的文件中使用模板(这提高了可维护性),但仍然使用模板属性来保证postLink事件的正确顺序
我现在处理角度的对象。关键是在angular应用程序启动时预加载所有模板。然后使用
$templateCache.get
方法填充组件的模板属性。这让我找到了解决方案。在javascript代码中,我还使用了两个组件和控制器。设置基本相同。我之所以使用require,是因为我希望能够在选项卡中转移自定义内容。但是关于templateUrl的子元素被异步加载的注释就是答案!事实上,如果我切换到文字模板,它会工作!
/**
* 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;