从Directive调用时,Typescript Angularjs控制器范围未定义

时间:2014-06-26 05:30:20

标签: javascript angularjs controller angularjs-directive typescript

我对Angularjs和Typescript很新。

我会在这里尽量简短:

指令(指令/ BikeDirective.ts):

class BikeDirective {
    constructor() {
        var directive: ng.IDirective = {};
        directive.restrict = "E";
        directive.scope = {
            move: "="
        };
        directive.template = '<div>The bike</div>';
        directive.link = (scope, element, attrs: any) => {
            element.on('click', (e) => {
                scope.move('moving!');
            });
        }
        return directive;
    }
}
export = BikeDirective;

Controller(controllers / MyController):

class MyController {
    whatever: string;
    constructor(public scope) {
        this.whatever = "Whatever";
        scope.vm = this;
    }
    onMove(msg: string) {
        console.log(this.whatever);
    }
}
export = MyController;

HTML:

    <div ng-controller="myController">
        <my-bike move="vm.onMove"></my-bike>
        <my-bike move="vm.onMove"></my-bike>
    </div>

app.ts

import MyController = require("controllers/MyController");
import BikeDirective = require("directives/BikeDirective");

class app {
    constructor() {
        var app = angular.module('app', [])
            .controller('myController', ['$scope', MyController])
            .directive('myBike', [BikeDirective]);
    }
}
export = app;

main.ts

require.config({
    baseUrl: '.',
    paths: {
        jquery: './Scripts/jquery-2.1.0',
        angular: './Scripts/angular'
    },
    shim: {
        'angular': {
            exports: 'angular'
        }
    }
}); 
require(['app','angular','jquery'], (app, angular, $) => {
    new app;
    angular.bootstrap(document.body, ['app']);
});

我希望上面的代码是自我解释的。基本上,我想要做的是点击其中一辆自行车(my-bike指令)运行MyController.onMove()函数。一切正常。我遇到的唯一问题是,当执行onMove时,console.log(this.whatever)输出undefined,不应输出字符串&#34;无论&#34 ;?似乎myMtroller的范围在onMove()存根中不可用。

我在简单的Angularjs(没有TypeScript)中尝试了这个并且它工作正常,我错过了什么。

以前是否有人经历过这个?

我在此视频中遵循了Basarat使用的.vm技术:http://www.youtube.com/watch?v=WdtVn_8K17E

由于

1 个答案:

答案 0 :(得分:3)

问题

问题在于move="vm.onMove"您将函数的引用传递给指令,即

        directive.scope = {
            move: "="
        };

调用对函数的引用会将其与this断开连接。

快速修复:

onMove = (msg: string) => {
    console.log(this.whatever); //OKAY
}

这再解释了thishttps://www.youtube.com/watch?v=tvocUcbCupA&hd=1

更好的解决方法:

不要将函数传递给指令,即不要将=与函数一起使用。而是使用&

        directive.scope = {
            move: "&"
        };

然后从你的html中调用它,即<my-bike move="vm.onMove()"></my-bike>。使用vm.调用函数,即vm.onMove()可确保函数内的this正确。

也与此问题无关

在角度上下文中未调用

element.on回调...因此您可能希望将回调包装在$scope.$apply