2014-10-16 111 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只返回一個承諾。