2017-03-08 91 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构造函数中做到这一点。

相关问题