2017-01-10 6 views
1

私は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); 
}; 
} 

コンソール出力:

  • $のOnInit
  • addTab
  • addTab
  • addTab
  • $ポストリンクここでタブコンポーネントのコードです。 nlのタブが追加されました:3

しかし、私は同じタイプコピーで同じことをしようとすると、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); 
    } 
} 
} 

/タブ/タブ:ここで

は、コードの一部です。 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); 
    } 

} 
} 

テンプレートは同じです。

今コンソール出力は次のようになります。

  • $のOnInit
  • $ポストリンク。タブのNRが追加さ:0
  • angular.js:13920例外TypeError:私はここで何かを設定することはできませんプロパティ '選択された' 未定義
  • addTab
  • addTab
  • addTab

足りませんか?

答えて

0

さて、あなたは今、別のアプローチを使用しています。 1つのコントローラ内の配列にプッシュする前に。これで2つのコンポーネントとコントローラが使用できるようになりました。

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; 

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.

代わりのrequireを使用して、あなたは多分子供たちにtabs配列をバインドする必要があります。

+0

JavaScriptコードでは、2つのコンポーネントとコントローラも使用しています。設定は基本的に同じです。私はタブでカスタムコンテンツをクロールできるようにしたいのでrequireを使用しています。しかし、templateUrlが非同期にロードされている子要素についての発言は、ここの答えです!実際、リテラルテンプレートに切り替えると動作します! – Stif

1

@ kuhnroyalの答えが正しいです。しかし、同じ問題を抱えている他の人にとっては役に立つかもしれないので、フォローアップを投稿したかったのです。私は別のファイル(メンテナンス性を向上させる)でテンプレートを扱うことができるソリューションを見つけましたが、テンプレートプロパティを使用してpostLinkイベントの正しい順序を保証しています。

私は現在角度のオブジェクト$templateCacheで動作します。キーは、角型アプリケーションの起動時にすべてのテンプレートをプリロードすることです。 $ templateCache.getメソッドを使用して、コンポーネントのtemplate-propertyを入力します。このpostは私にその解決策を導いた。

関連する問題