2014-02-10 19 views
13

我正在使用Asp.Net Web API和AngularJS開發SPA。我也使用TypeScript來獲得靜態類型。所以,我添加了DefinitelyTyped angularjs。

由於我使用RESTfull服務。我想過使用$ angularjs的資源。現在我的資源沒有任何內置的PUT http方法。所以我決定添加我自己的如下。

var employees = $resource('/api/employee/:id',{id:'@id'},{"update":{ method: "PUT", isArray:false }}; 

現在,您可以看到,它在普通的AngularJS中很容易做到。我想通過TypeScript路線並定義延伸IResourceClass的自定義界面。這個界面的文檔就是這樣解釋的。

//使用默認操作的每個資源的Baseclass。 //如果你爲資源定義了新的動作,你將需要 //來擴展這個接口並且爲它指定ResourceClass。

我真的無法弄清楚如何擴展這個接口。它不斷提出有關語法的一些錯誤。有人可以解釋如何擴展這個接口並添加Update方法,然後在我的控制器上調用PUT方法。

+0

請讓我知道我的答案是否有幫助,或者如果您仍然留在評論中。謝謝。 – Scott

+0

在AngularJS DefinitelyTyped頁面上,有一些非常有用的關於$資源使用情況的TypeScript文檔 - https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/angularjs –

回答

28

首先定義您的模型,將描述您的員工的界面。

// Define an interface of the object you want to use, providing it's properties 
interface IEmployee extends ng.resource.IResource<IEmployee> 
{ 
    id: number; 
    firstName : string; 
    lastName : string; 
} 

然後創建一個接口,描述您將創建的資源。

// Define your resource, adding the signature of the custom actions 
interface IEmployeeResource extends ng.resource.IResourceClass<IEmployee> 
{ 
    update(IEmployee) : IEmployee; 
} 

創建EmployeeResource工廠:

var myApp = angular.module('myApp', ['ngResource']).factory('EmployeeResource', 
    ['$resource', ($resource : ng.resource.IResourceService) : IEmployeeResource => { 

     // Define your custom actions here as IActionDescriptor 
     var updateAction : ng.resource.IActionDescriptor = { 
      method: 'PUT', 
      isArray: false 
     }; 

     // Return the resource, include your custom actions 
     return <IEmployeeResource> $resource('/api/employee/:id', { id: '@id' }, { 
      update: updateAction 
     }); 

    }]); 

注入你EmployeeResource到控制器:

myApp.controller('TestCtrl', ['$scope', 'EmployeeResource', ($scope, Employee : IEmployeeResource) => 
{ 
    // Get all employees 
    var employees : Array<IEmployee> = Employee.query(); 

    // Get specific employee, and change their last name 
    var employee : IEmployee = Employee.get({ id: 123 }); 
    employee.lastName = 'Smith'; 
    employee.$save(); 

    // Custom action 
    var updatedEmployee : IEmployee = Employee.update({ id: 100, firstName: "John" }); 
}]); 

創建一個新員工的實例:

ÿ您可以通過new工廠創建IEmployee類型的實例。

myApp.controller('TestCtrl', ['$scope', 'EmployeeResource', ($scope, Employee : IEmployeeResource) => 
{ 
    var myEmployee : IEmployee = new Employee({ firstName: "John", lastName: "Smith"}); 
    myEmployee.$save(); 
} 

因此,在上述情況中,我們注入我們的IEmployeeResourceEmployee。那麼我們可以用new這個對象來創建一個IEmployee

+0

這確實回答了我的問題,但並未提供確切的解決方案尋找。我想有一個通用的方法來定義$資源上的更新。所以,我不必在每個控制器中聲明它。但感謝解決方案。 –

+1

如果你發佈的答案,確保他們至少編譯。我認爲 [$資源,($資源:ng.resource.IResourceService):IEmployeeResource => 必須 [ '$資源',($資源:ng.resource.IResourceService):IEmployeeResource => 介意報價。 – LocalJoost

+3

@LocalJoost我修復了這個小錯字。如果你發現錯別字可以自由編輯它們,那就是SO方式。 *分別請不要告訴我如何回答你相對較新的社區中的問題,這是無禮的。* – Scott

1

我完全斯科特的答案一致:https://stackoverflow.com/a/21786326/2677975

我有一個加法: 在我的項目,我已經創建類ServiceModel<T>,它實現了接口IActionDescriptor

module Common.ApiService { 
    export class HttpHeaders { 
     'Content-Type': string; 
     Accept: string; 
    } 

    export class ServiceModel<T> implements ng.resource.IActionDescriptor { 
     public method: string = 'GET'; 
     public params: T; 
     public isArray: boolean = false; 
     public url: string; 
     public headers: HttpHeaders = new HttpHeaders() 
    } 
} 

然後,我可以安裝在我的控制器的方法,正如斯科特做了,但是現在,在IDE將對頭(以及後來是否存在params)

export interface IProfileServiceResource extends ng.resource.IResourceClass<IProfileDataModelDef> { 
    SaveProfileImage(profileImageUri: Profile.Model.UserProfileModel): ng.resource.IResource<Array<any>>; 
} 

export class ProfileApiService 
    implements Common.ApiService.IApiServiceBase<IProfileServiceResource> { 

    public SaveProfileImage: Common.ApiService.ServiceModel<Profile.Model.UserProfileModel>; 

    constructor() {  
     this.SaveProfileImage = new Common.ApiService.ServiceModel<Profile.Model.UserProfileModel>(); 
     this.SaveProfileImage.method = "POST"; 
     this.SaveProfileImage.url = "/api/Profile/SaveProfileImage"; 
     this.SaveProfileImage.headers["Content-Type"] = 'application/json'; 
} 

I型完成作爲附加答案,因爲它僅用於提供headersparams的類型。