Redplane
Redplane

Reputation: 3151

AngularJS , Typescript & Oclazyload cannot recognize scope

I'm changing my existing AngularJS app from (AngularJS + ES5 + Webpack) to (AngularJS + Typescript + Webpack)

This is one of my module implementation:

login.controller.ts

import {ILoginScope} from "./login.scope";
import {LoginViewModel} from "../../../view-models/user/login.view-model";

export class LoginController implements ng.IController{

    //#region Properties

    public email: string = '123456';

    //#endregion

    //#region Constructor

    /*
    * Initialize controller with injectors.
    * */
    public constructor(public $scope: ILoginScope){
        this.$scope.loginModel = new LoginViewModel();
        this.$scope.loginModel.email = '123';
        this.$scope.hasEmail = this.hasEmail;
    }

    //#endregion

    //#region Methods

    //#endregion

    //#region Events

    public clickLogin(): void {
        console.log('Hello world');
    }

    public hasEmail(): boolean{
        let loginModel = this.$scope.loginModel;
        if (!loginModel || !loginModel.email)
            return false;

        return true;
    }

    //#endregion
}

login.scope.ts

import {LoginViewModel} from "../../../view-models/user/login.view-model";

export interface ILoginScope extends ng.IScope {

    //#region Properties

    /*
    * Login information.
    * */
    loginModel: LoginViewModel;

    //#endregion

    //#region Methods

    /*
    * Called when login is clicked.
    * */
    clickLogin: Function;

    hasEmail: () => boolean;

    //#endregion
}

login.module.ts

import {StateProvider} from "@uirouter/angularjs";
import {UrlStatesConstant} from "../../../constants/url-states.constant";
import {module} from 'angular';


export class LoginModule {

    //#region Constructors

    public constructor(private $stateProvider: StateProvider) {
        $stateProvider
            .state(UrlStatesConstant.LoginStateName, {
                url: UrlStatesConstant.LoginStateUrl,
                controller: 'loginController',
                templateProvider: ['$q', ($q) => {
                    // We have to inject $q service manually due to some reasons that ng-annotate cannot add $q service in production mode.
                    return $q((resolve) => {
                        // lazy load the view
                        require.ensure([], () => resolve(require('./login.html')));
                    });
                }],
                parent: UrlStatesConstant.AuthorizeLayoutName,
                resolve: {
                    /*
                    * Load login controller.
                    * */
                    loadLoginController: ($q, $ocLazyLoad) => {
                        return $q((resolve) => {
                            require.ensure([], (require) => {
                                // load only controller module
                                let ngModule = module('account.login', []);

                                // Import controller file.
                                const {LoginController} = require("./login.controller");
                                ngModule.controller('loginController', LoginController);
                                $ocLazyLoad.load({name: ngModule.name});
                                resolve(ngModule.controller);
                            })
                        });
                    }
                }
            });

    }

    //#endregion
}

And this is how I registered my typescript angularjs module to existing es5 angularjs application:

module.exports = (ngModule) => {
    // Load routes.
    let login = require('./login');
    ngModule.config(($stateProvider) => login.LoginModule($stateProvider));
};

When I run the application and access to login page There is an error thrown in my developer console:

TypeError: Cannot read property 'loginModel' of undefined at ChildScope.LoginController.hasEmail (login.controller.ts:26)

This is the generated source map:

src-map

From what the error message says, the this.$scope at line 26 cannot be recognized even it has been declared as public $scope: ILoginScope in the constructor.

What wrong am I doing ?

Thank you,

Upvotes: 1

Views: 208

Answers (0)

Related Questions