背景
在我正在进行的项目中,我们已经为系统的UI部分采用了Angular Material Design框架。我们将此与AngularJS 1.6.2和TypeScript 2.1.5结合使用。
我们一直在遇到的一条建议就是使用AngularJS生命周期钩子,以便在AngularJS被弃用以支持Angular 2时做好准备。具体来说,引入生命周期钩子以使其更容易升级,因为这些钩子 - 其中$onInit()
是成员 - 是纯粹基于组件的设置的一部分,这是Angular 2的主要特性。
问题:
我们发现,当您定义一个实现angular.IController
的对话框控制器,并且$onInit()
定义了内容时......这些内容不会被执行。
问题示例TypeScript:
// 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
已解雇的消息。
因此,这导致我......
问题:为什么如果Material Design Dialog控制器实现IController
,显然生命周期挂钩不会触发?
答案 0 :(得分:1)
我从AngularJS开始,我最近在实习期间遇到了同样的问题。我认为问题是你的ModalController
没有被称为组件(它被$mdDialog
调用)所以它没有任何生命周期。
要解决此问题,您必须明确调用$onInit
方法。也许你可以在你的ModalController
构造函数中做到这一点。
答案 1 :(得分:-2)
在您的代码中,您有angular.module('app').controller('modalController', ModalController);
。我没有在你的代码中看到modalController
,所以怀疑这个控制器实际上从未被触发过。