【问题标题】:TypeScript Controller not handling HTTP promisesTypeScript 控制器不处理 HTTP 承诺
【发布时间】:2014-12-12 04:25:40
【问题描述】:

我一直在学习 Angular,一切都很顺利。我决定尝试将 TypeScript 合并到其中,并在我一直在从事的现有 Angular/WebApi 项目中编写了一个小型测试控制器。

控制器“工作”并初始化得很好,但是,当设置为 HTTP 承诺时,我的 $scope 属性没有被更新。我使用 TypeScript 生成的 JS 文件附加了我的问题的“工作”示例。调试时,我可以看到then 在promise 上被触发,我期望的数据是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 可以很好地返回响应。

下面是我的控制器的 JavaScript 版本的实际可运行的 sn-p 代码。

(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>

谁能告诉我我做错了什么?在我看来一切都很好。

【问题讨论】:

  • 似乎 stackexchange 调用不起作用。检查这个 JSFiddle 是否正在工作。 jsfiddle.net/HB7LU/7382
  • @KrishnaTejaVeeramachaneni 不过这很奇怪。使用 URL 时控制台中没有错误报告,并且在本地调用我自己的服务时没有错误,但结果完全相同(页面上的{} 而不是Hello!)。这就是在api 上调用一个其他控制器可以调用的方法。我看到你的例子虽然有效。我现在很迷茫。
  • 不知道为什么您在控制台中没有看到错误,但我能够在 chrome 控制台中看到 404 错误。
  • 谁知道拨打getTestResponse().then(...) 的答案,请取消删除您的答案。这是正确的。
  • @KrishnaTejaVeeramachaneni 我没有收到 404 调用该 URL。

标签: angularjs typescript angular-promise


【解决方案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 语句返回来自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>

【讨论】:

  • 谢谢。我在我的基础中使用了一个错误的地方作为设置 TypeScript 类的模板。我在其他任何地方都使用then。哦! TypeScript 修复是 this.api.getTestResponse().then((v: any): void =&gt; this.$scope.tableId = v);
【解决方案2】:

好的,这就是问题所在。您正在尝试将您的响应设置为实际的回调函数。 相反,您必须使用从 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 只返回一个承诺。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    相关资源
    最近更新 更多