我是Angularjs和Typescript的新手。

我会在这里尽量简短:

指令(directives / 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>

应用程序
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;

主要
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)输出未定义,它不应该输出字符串“whatever”吗?似乎MyController的范围在onMove()存根中不可用。

我在普通的Angularjs(没有TypeScript)中尝试过,并且工作正常,是否缺少某些东西。

有人经历过吗?

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

谢谢

最佳答案

问题

问题出在move="vm.onMove"中,您正在将对函数的引用传递到指令中,即

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

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

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

这进一步解释了this:https://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

10-06 12:22