angularjs - Typescript + Angular "controller as"Sidewaffle 模板开箱即用

标签 angularjs typescript typescript1.4 sidewaffle

请原谅我后面的代码墙,但每个 block 只有一个小的变化,每个变化都有注释。

我正在尝试使用 Sidewaffle 模板包附带的 Angular+Typescript“ Controller 作为”模板。这就是开箱即用的模板。我在这里对模板所做的唯一修改是注释、空格以及将“app1”重命名为“app”:

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)
    ]);

首先要注意的是,由于 Controller 类上的静态 controllerId 成员和 controllerId 成员,它甚至不会编译 Icontroller接口(interface)。由于接口(interface)的成员需要在类的类型的实例端实现,所以这是行不通的。

这很烦人,但很容易绕过,尽管这样做会丢失一些类型检查:

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); 
    }
]);

现在,当我们尝试在 View 中使用“controller as”语法时,Angular 无法找到别名 Controller —— View 绑定(bind)到一个空对象。

据我所知,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. 为什么要将 Controller 构造函数包装在 lambda 中以传递给 Angular 的 controller() 方法,而不是直接传递构造函数?
  2. 为什么模板在类上有一个静态成员,它试图通过类实现的接口(interface)上的成员强制执行?

我唯一的猜测是,这两个问题在 Typescript 和 Angular 的某些早期版本组合中都不是问题,但我不知道,因为我对这两个问题都很陌生。我正在使用 Typescript v1.4 和 Angular v1.3.14

最佳答案

Why would you ever want to wrap the controller constructor in a lambda to hand to Angular's controller() method instead of handing over the constructor directly?

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

Why would the template have a static member on a class that its trying to enforce with a member on the interface that the class implements

关于 controllerId: string;//This won't work... 在接口(interface)上拥有一个成员并使用类实现该接口(interface)意味着该类的实例将拥有该成员。然而,你想说的是类(class)有这个成员。这不能通过实现接口(interface) 来完成。

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

var mustHaveId:{controllerId:string};

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

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

关于angularjs - Typescript + Angular "controller as"Sidewaffle 模板开箱即用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28861916/

相关文章:

node.js - TS2688 : Cannot find type definition file for 'node' with @types/node installed

javascript - 在 angularjs 中为什么我们在 angular.module() 函数中使用 [] ?

javascript - AngularJS:OrderBy Descending(空条目)

javascript - 排列表格后保持所选元素突出显示

javascript - 如何使用 AngularJS 创建 html 页面模板并将 Controller 动态绑定(bind)到它?

typescript - tsconfig "module"属性与节点服务器 + 创建 React 应用程序

typescript - 有没有办法在 vuejs 中获取组件的类型?

typescript - 在 TypeScript 中键入具有联合类型的数组?

angularjs - IIS 7.5 中不允许使用 Type Script + Angular Js + Web API Status 405 的方法

javascript - 使用 TypeScript lib.core.d.ts 而不是 lib.d.ts