打字稿+ Angular"控制器为" Sidewaffle模板不能开箱即用

时间:2015-03-04 18:19:07

标签: angularjs typescript typescript1.4 sidewaffle

请原谅我后面的代码墙,但每个块只有一个小的更改,每个更改都会被评论。

我试图使用Angular + Typescript"控制器作为" Sidewaffle模板包附带的模板。这就是模板开箱即用的样子。我在这里对模板所做的唯一修改是评论,空白和重命名' app1'到应用程序':

interface ItestControllerScope extends ng.IScope {
    vm: testController;
}
interface ItestController {
    greeting: string;
    controllerId: string; //This won't work...
    changeGreeting: () => void;
}
class testController implements ItestController {
    static controllerId: string = "testController"; //...because this is static.
    greeting = "Hello";

    constructor(private $scope: ItestControllerScope, private $http: ng.IHttpService, private $resource: ng.resource.IResourceService) {
    }
    changeGreeting() {
        this.greeting = "Bye";
    }
}
app.controller(testController.controllerId,
    ['$scope', '$http', '$resource', ($scope, $http, $resource) =>
        new testController($scope, $http, $resource)
    ]);

首先要注意的是,由于控制器类上的静态controllerId成员和controllerId所需的Icontroller成员,它甚至无法编译接口。由于界面的成员需要在类的类型的实例端实现,这不会起作用。

那令人讨厌,但很容易解决,虽然我们通过这样做失去了一些类型检查:

interface ItestControllerScope extends ng.IScope {
    vm: testController;
}
interface ItestController {
    greeting: string;
    changeGreeting: () => void;
}
class testController implements ItestController {
    //we leave the static member on the class and remove the member
    //from the interface
    static controllerId: string = "testController";
    greeting = "Hello";

    constructor(private $scope: ItestControllerScope, private $http: ng.IHttpService, private $resource: ng.resource.IResourceService) {
    }
    changeGreeting() {
        this.greeting = "Bye";
    }
}
app.controller(testController.controllerId,
    ['$scope', '$http', '$resource', ($scope, $http, $resource) =>
        new testController($scope, $http, $resource)
    ]);

现在编译,但问题是如何将app.controller()的调用转换为javascript。它不是直接将构造函数传递给app.controller(),而是包含在一个匿名函数中,我们最终得到的是构造函数中的构造函数:

var testController = (function () {
    function testController($scope, $http, $resource) {
        this.$scope = $scope;
        this.$http = $http;
        this.$resource = $resource;
        this.greeting = "Hello";
    }
    testController.prototype.changeGreeting = function () {
        this.greeting = "Bye";
    };
    testController.controllerId = "testController";
    return testController;
})();
app.controller(testController.controllerId,
    ['$scope', '$http', '$resource',
    //Why won't this work? Why would we want to do this in the first place?
    function ($scope, $http, $resource) { 
        return new testController($scope, $http, $resource); 
    }
]);

现在我们尝试将"控制器用作"在视图中的语法,Angular无法找到别名控制器 - 视图绑定到空对象。

我能说的最好,Typescript模板 应该是这样的:

interface ItestControllerScope extends ng.IScope {
    vm: testController;
}
interface ItestController {
    greeting: string;
    changeGreeting: () => void;
}
class testController implements ItestController {
    static controllerId: string = "testController";
    greeting = "Hello";

    constructor(private $scope: ItestControllerScope, private $http: ng.IHttpService, private $resource: ng.resource.IResourceService) {
    }

    changeGreeting() {
        this.greeting = "Bye";
    }
}
//Now we're passing the controller constructor directly instead of
//wrapping the constructor call in another constructor
app.controller(testController.controllerId,
    ['$scope', '$http', '$resource',testController]);

编译成这个javascript:

var testController = (function () {
    function testController($scope, $http, $resource) {
        this.$scope = $scope;
        this.$http = $http;
        this.$resource = $resource;
        this.greeting = "Hello";
    }
    testController.prototype.changeGreeting = function () {
        this.greeting = "Bye";
    };
    testController.controllerId = "testController";
    return testController;
})();

app.controller(testController.controllerId,
    ['$scope', '$http', '$resource', testController]);

工作正常。所以我有两个主要问题:

  1. 为什么你想要将控制器构造函数包装在lambda中以交给Angular的controller()方法而不是直接移交构造函数?
  2. 为什么模板在类上尝试使用类实现的接口上的成员强制执行静态成员?
  3. 我唯一的猜测是,这些问题在早期的一些Typecript和Angular版本的组合中都不是问题,但我不知道,因为我对两者都相当新。我使用的是Typescript v1.4和Angular v1.3.14

2 个答案:

答案 0 :(得分:1)

  

为什么你想将控制器构造函数包装在lambda中以交给Angular的controller()方法而不是直接移交构造函数?

你不会。我不是https://www.youtube.com/watch?v=WdtVn_8K17E

  

为什么模板在类上有一个静态成员,它试图用类实现的接口上的成员强制执行

关于controllerId: string; //This won't work...在接口上拥有成员并使用类实现该接口意味着类的实例将具有此成员。你要说的是该类有这个成员。这不能通过实现接口来完成。

您可以通过其他方式确保这一点:

var mustHaveId:{controllerId:string};

class Fail{}
class Pass{static controllerId = "Pass"}

mustHaveId = Fail; // Error 
mustHaveId = Pass; // Pass

答案 1 :(得分:1)

查看source code on Github显示有问题的模板已“更新为Typescript 1.0和Angular 1.3兼容”,因此,对于Angular和Typescript的先前版本的某些组合,模板中的所有内容都必须曾经在过去的某个时间工作过。

我在更新的文件中解决了我遇到的两个问题,这些更改与我为使事情运行所做的更改类似。 Sidewaffle模板包尚未相应更新。

更新:在撰写本文时,最新版本的Sidewaffle模板包含固定模板。