2014-10-16 62 views
0

我一直在学习Angular,一切都很顺利。我决定尝试将TypeScript整合到此中,并在我一直在研究的已有的Angular/WebApi项目中编写了一个小型测试控制器。TypeScript控制器不处理HTTP承诺

控制器“工作”并初始化很好,但是,我的$scope属性在设置为HTTP承诺时未更新。我使用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>

谁能居然告诉我什么,我做错了什么?一切看起来都很好。

+0

似乎stackexchange调用不起作用。检查这个JSFiddle是否正在工作。 http://jsfiddle.net/HB7LU/7382/ – 2014-10-16 17:51:02

+0

@KrishnaTejaVeeramachaneni虽然这是奇怪的事情。使用URL时控制台中没有错误报告,并且在本地调用我自己的服务时没有错误,但结果完全相同(页面上的'{}'而不是'Hello!')。这就是调用其他控制器可以调用的'api'方法。我看到你的例子有它的工作。我现在很失落。 – TyCobb 2014-10-16 17:54:25

+0

不知道为什么你没有在控制台中看到错误,但我能够在Chrome控制台中看到404错误。 – 2014-10-16 18:02:07

回答

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>

+0

谢谢。我使用了我的基地中错误的一个地方作为设置TypeScript类的模板。我在其他地方使用'然后'。 D'OH! TypeScript修正是this this.api.getTestResponse()。then((v:any):void => this。$ scope.tableId = v);' – TyCobb 2014-10-16 19:12:29

1

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

这里是API函数

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

在这里你必须设置绑定到用户界面的响应特性控制器代码。

_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调用为例。 如果您有任何问题,请告诉我。

所以,在你的打字稿的代码,你必须改变

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

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

,让你的API只返回一个承诺。