2017-03-08 90 views
1

背景:
在我正在開發的一個項目上,我們爲系統的UI部分採用了Angular Material Design框架。我們將此與AngularJS 1.6.2和TypeScript 2.1.5結合使用。

我們一直在遇到的一條建議是使用AngularJS生命週期鉤子,以便在AngularJS被棄用而支持Angular 2時做好準備。具體來說,引入了生命週期鉤子,以便更容易升級,因爲這些鉤子鉤 - 其中$onInit()是一員 - 是純粹基於組件的配置,它的角2

問題的一個主要特徵的一部分:
我們發現,當你定義一個對話框控制器執行angular.IController,並且具有用內容定義的$onInit() ...這些內容不被執行。

問題實施例打字稿:

// Bootstrap Angular to our example. 
class App { 
    public constructor() { 
     angular.module('app', ['ui.router', 'ngMaterial']); 
    } 
} 

let app: App = new App(); 

// Set up routing for the example... 
class RouteConfig { 
    constructor(
     $stateProvider: angular.ui.IStateProvider, 
     $urlRouterProvider: angular.ui.IUrlRouterProvider, 
     $locationProvider: angular.ILocationProvider 
    ){ 
     $stateProvider.state('Main', { 
      url: '/Main', 
      templateUrl: 'app/Main.html', 
      controller: 'mainController' 
     }); 

     $urlRouterProvider.otherwise('/Main'); 

     $locationProvider.html5Mode({ 
      enabled: true, 
      requireBase: false 
     }); 
    } 
} 

angular.module('app').config(['$stateProvider', '$urlRouterProvider', '$locationProvider', RouteConfig]); 

// Controller for the page that will launch the modal... 
class MainController implements angular.IController { 
    public static $inject: string[] = ['$mdDialog']; 
    public constructor(public $mdDialog: angular.IDialogService) { 
    } 

    public $onInit(): void { 
     console.log('This works.'); 
    } 

    public onButtonClick(): void { 
     this.$mdDialog.show({ 
      controller: ModalController, 
      controllerAs: '$ctrl', 
      templateUrl: '/App/myModalTemplate.html', // Contents of modal not important. 
      parent: angular.element(document.body), 
      fullscreen: true 
     }) 
      .then(() => console.log('Modal closed.'), 
       () => console.log('Modal cancelled.')); 
    } 
} 

angular.module('app').controller('mainController', MainController); 

// Controller for the actual modal that should be triggering $onInit. 
class ModalController implements angular.IController { 
    public static $inject: string[] = ['$mdDialog']; 
    public constructor(public $mdDialog: angular.IDialogService) { 
     alert('ModalController.ctor fired!'); 
    } 

    public $onInit(): void { 
     // PROBLEM! This never actually executes. 
     alert('$onInit fired on modal!'); 
    } 

    public ok(): void { 
     this.$mdDialog.hide(); 
    } 
} 

angular.module('app').controller('modalController', ModalController); 

應用程序/ main.html中

<div ng-controller="mainController as $ctrl" 
    md-content 
    layout-padding> 
    <h4>Modal Lifecycle Hook Problem Example</h4> 
    <md-button class="md-raised md-primary" 
       ng-click="$ctrl.onButtonClick()"> 
     Show Modal 
    </md-button> 
</div> 

應用程序/ myModalTemplate.html:

<md-dialog> 
    <md-toolbar class="md-theme-light"> 
     <h2>Modal</h2> 
    </md-toolbar> 
    <md-dialog-content class="md-padding"> 
     Stuff, y'all. 
    </md-dialog-content> 
    <md-dialog-actions> 
     <md-button class="md-primary" 
        ng-click="$ctrl.ok()"> 
      OK 
     </md> 
    </md-dialog-actions> 
</md-dialog> 

如果您設置了所有這些東西,並運行該項目,您將看到一個帶有按鈕的頁面。當你點擊按鈕時,你只會得到一個警報 - 構造函數已經被觸發。我在期待,你會得到兩個警報:構造函數發起的消息,以及$onInit發起的消息。

因此,這導致了我的...

問題:爲什麼說,如果材料設計對話控制器實現IController,顯然是生命週期掛鉤不火?

+1

我剛剛被這個問題困住了:$ onInit在「普通」控制器中調用,但不是mdDialog控制器。 你有沒有想過? – LucasM

+2

相關搜索:https://github.com/angular/material/issues/9259 – LucasM

回答

-1

在您的代碼中有angular.module('app').controller('modalController', ModalController);。我沒有在代碼中的任何地方看到modalController,所以懷疑這個控制器實際上從未被觸發。

+0

這個答案沒有幫助的原因是因爲ModalController被定義爲這樣,並且被用作這樣的。您會注意到我們在TypeScript中的$ mdDialog調用中使用了'ModalController'。這段代碼實際上工作,並導致模態出現。問題是'$ onInit()'永遠不會被觸發。我能做些什麼來使這個問題更容易混淆? –

1

我開始與AngularJS和我最近有同樣的問題,在我的實習期間。我認爲問題在於你的ModalController沒有被稱爲一個組件(它被稱爲$mdDialog),所以它沒有任何生命週期。

要解決此問題,您必須明確調用您的$onInit方法。也許你可以在你的ModalController構造函數中做到這一點。

相關問題