TypeScript Controller不处理HTTP承诺

时间:2014-10-16 17:37:01

标签: angularjs typescript angular-promise

我一直在学习Angular,一切都很顺利。我已经决定尝试将TypeScript合并到这里,并在我已经存在的已经存在的Angular / WebApi项目中编写了一个小型测试控制器。

控制器“工作”并初始化很好,但是,当设置为HTTP承诺时,我的$scope属性没有被更新。我使用TypeScript生成的JS文件附加了我的问题的“工作”示例。在调试时,我可以看到then触发了承诺和我期望的数据return,但页面显示{}

这是我的实际TypeScript文件。

/// <reference path="../../tds/angularjs/angular.d.ts" />
module RecordEditor {
    export interface Scope extends ng.IScope{
        tableId: any;
    }

    export class Controller {
        $scope: Scope;
        api : any;
        constructor($scope: Scope, myApi: any) {
            this.api = myApi;
            this.$scope = $scope;
            this.$scope.tableId = this.api.getTestResponse();
        }
    }
}

var app = angular.module("myApp");
app.controller("RecordEditor.Controller", ['$scope', 'myApi', RecordEditor.Controller]);

那个控制器是我用TypeScript实际写的唯一东西。所有其他控制器都使用JavaScript,我构建的api返回响应就好了。

以下是带有我的Controller的JavaScript版本的实际可运行代码段。

(function() {

  var app = angular.module('myApp', []);

}());

(function() {
  var myApi = function($http) {

    var getTestResponse = function() {
      // Hope it is okay to use SE API to test this question. Sorry if not.
      return $http.get("https://api.stackexchange.com/2.2/sites")
        .then(function(response) {
          return "Hello!";
        });
    };

    return {
      getTestResponse: getTestResponse,
    };

  };

  var module = angular.module("myApp");
  module.service("myApi", ['$http', myApi]);
}());

var RecordEditor;
(function(RecordEditor) {
  var Controller = (function() {
    function Controller($scope, myApi) {
      var _this = this;
      this.api = myApi;
      this.$scope = $scope;
      this.$scope.response = this.api.getTestResponse();

      this.$scope.ctorTest = 42;
    }
    return Controller;
  })();
  RecordEditor.Controller = Controller;
})(RecordEditor || (RecordEditor = {}));

var app = angular.module("myApp");
app.controller("RecordEditor.Controller", ['$scope', 'myApi', RecordEditor.Controller]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<div ng-app="myApp" ng-controller="RecordEditor.Controller">
  <div >
    Scope property set in constructor: {{ctorTest}}
  </div>
  
  <div >
    Scope response value: {{response}}
  </div>

  <div >
    Scope response should have been "Hello!"
  </div>
</div>

任何人都可以告诉我我做错了什么吗?一切看起来都很好。

2 个答案:

答案 0 :(得分:1)

var getTestResponse = function() {
  return $http.get("https://api.stackexchange.com/2.2/sites")
    .then(function(response) {
      return "Hello!"; // <-- does not do what you think it does
    });
};

/** elsewhere **/
this.$scope.response = this.api.getTestResponse();

此处的内部return语句 not getTestResponse返回值。相反,它从Promise 返回一个值,它基本上被丢弃了。 getTestResponse立即返回一个Promise对象,该对象对于绑定到作用域没有特别的用途。

JS的固定版本:

(function() {

  var app = angular.module('myApp', []);

}());

(function() {
  var myApi = function($http) {

    var getTestResponse = function() {
      // Hope it is okay to use SE API to test this question. Sorry if not.
      return $http.get("https://api.stackexchange.com/2.2/sites")
        .then(function(response) {
          return "Hello!";
        });
    };

    return {
      getTestResponse: getTestResponse,
    };

  };

  var module = angular.module("myApp");
  module.service("myApi", ['$http', myApi]);
}());

var RecordEditor;
(function(RecordEditor) {
  var Controller = (function() {
    function Controller($scope, myApi) {
      var _this = this;
      this.api = myApi;
      this.$scope = $scope;
      /** FIXED **/
      this.api.getTestResponse().then(function(v) { _this.$scope.response = v; });

      this.$scope.ctorTest = 42;
    }
    return Controller;
  })();
  RecordEditor.Controller = Controller;
})(RecordEditor || (RecordEditor = {}));

var app = angular.module("myApp");
app.controller("RecordEditor.Controller", ['$scope', 'myApi', RecordEditor.Controller]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<div ng-app="myApp" ng-controller="RecordEditor.Controller">
  <div >
    Scope property set in constructor: {{ctorTest}}
  </div>
  
  <div >
    Scope response value: {{response}}
  </div>

  <div >
    Scope response should have been "Hello!"
  </div>
</div>

答案 1 :(得分:1)

好的,这是问题所在。您正在尝试将响应设置为实际的回调函数。 相反,您必须使用从http调用获得的响应在回调内设置响应属性。

这是api函数

 var getTestResponse = function() {         
      return $http.get("http://vimeo.com/api/oembed.json?url=http%3A//vimeo.com/76979871");            
    };

这是您的控制器代码,您必须将响应属性设置为绑定到UI。

 _this.api.getTestResponse().success(function(resp) { 
      _this.$scope.response = resp.height; //I just used height property from response as example
  });

这是jsfiddle

http://jsfiddle.net/HB7LU/7386/

确保首先让stackexachange调用正常工作。我以vimeo调用为例。 如果您有任何问题,请告诉我。

因此,在TypeScript代码中,您必须更改

this.$scope.tableId = this.api.getTestResponse();

this.api.getTestResponse().then((resp) =>
{
    this.$scope.tableId = resp;
});

让你的API返回一个承诺。