2015-10-10 48 views
6

我試圖從角度控制器調用自定義過濾器,但出現錯誤: '無法調用鍵入缺少呼叫簽名'。嘗試在'錯誤TS2349:無法調用其類型缺少呼叫簽名的表達式'中調用自定義過濾器結果

我在最後一個項目中對此進行了這樣的實施,所以我對於什麼是錯誤感到不知所措。

該過濾器在此處不包含任何邏輯,因爲我需要先編譯它。

這裏是過濾器:

/// <reference path="../../typings/reference.ts" /> 

module app { 
'use strict'; 

/** 
* Filter models 
*/ 
export class ModelFilter { 
    public static Factory() { 
     return function(input: string) { 
      console.log(input); 
      return input; 
     } 
    } 
} 

angular.module('app') 
    .filter('modelFilter', [ModelFilter.Factory]); 
} 

而且控制器,其中其稱爲:

/// <reference path="../../typings/reference.ts" /> 

module app { 
'use strict'; 

interface ISearchController { 
    vehicles: IVehicles; 
    models: any; 
    setVehicles(): void; 
    updateModels(make: string): void; 
} 

class SearchController implements ISearchController { 

    static $inject = [ 
     'VehicleMakeService', 
     'VehicleModelService', 
     '$filter' 
    ]; 
    constructor(private vehicleMakeService: VehicleMakeService, 
       private vehicleModelService: VehicleModelService, 
       private $filter: ng.IFilterService, 
       public vehicles: IVehicles, 
       public models: any) { 

     this.setVehicles(); 
    } 

    setVehicles(): void { 
     this.vehicleMakeService.getVehicles().then((data) => { 
      this.vehicles = data; 
     }); 
    } 

    updateModels(make: string): void { 

     var test = this.$filter('modelFilter')(make); // Error here 
    } 
} 
angular.module('app').controller('SearchController', SearchController); 
} 

reference.ts:

/// <reference path="./tsd.d.ts" /> 

//grunt-start 
/// <reference path="../app/app.config.ts" /> 
/// <reference path="../app/app.module.ts" /> 
/// <reference path="../app/app.route.ts" /> 
/// <reference path="../app/home/home.controller.ts" /> 
/// <reference path="../app/home/home.route.ts" /> 
/// <reference path="../app/models/vehicles.model.ts" /> 
/// <reference path="../app/results/results.controller.ts" /> 
/// <reference path="../app/results/results.route.ts" /> 
/// <reference path="../app/services/cars.service.ts" /> 
/// <reference path="../app/services/vehicles.make.service.ts" /> 
/// <reference path="../app/services/vehicles.models.service.ts" /> 
/// <reference path="../app/templates/search.controller.ts" /> 
/// <reference path="../app/templates/search.filter.ts" /> 
//grunt-end 

tsd.d.ts:

/// <reference path="angularjs/angular.d.ts" /> 
/// <reference path="jquery/jquery.d.ts" /> 
/// <reference path="angular-ui-router/angular-ui-router.d.ts" /> 
/// <reference path="angularjs/angular-resource.d.ts" /> 

回答

10

修改工作示例:

/// <reference path="typings/angularjs/angular.d.ts" /> 

module app { 

    // ADDED <--- MODIFIED! 
    export interface MyModelFilter extends ng.IFilterService { 
     (name: 'modelFilter'): (input: string) => string; 
    } 

    /** 
    * Filter models 
    */ 
    export class ModelFilter { 
     public static Factory() { 
      return function(input: string) { 
       console.log(input); 
       return input; 
      } 
     } 
    } 

    angular.module('app') 
     .filter('modelFilter', [ModelFilter.Factory]); 
} 

module app { 

    class SearchController { 
     constructor(private $filter: MyModelFilter) { // <--- MODIFIED! 
     } 

     updateModels(make: string): void { 
      var test = this.$filter('modelFilter')(make); 
     } 
    } 
    angular.module('app').controller('SearchController', SearchController); 
} 

的問題是,打字稿使用以下definition

/** 
* $filter - $filterProvider - service in module ng 
* 
* Filters are used for formatting data displayed to the user. 
* 
* see https://docs.angularjs.org/api/ng/service/$filter 
*/ 
interface IFilterService { 
    (name: 'filter'): IFilterFilter; 
    (name: 'currency'): IFilterCurrency; 
    (name: 'number'): IFilterNumber; 
    (name: 'date'): IFilterDate; 
    (name: 'json'): IFilterJson; 
    (name: 'lowercase'): IFilterLowercase; 
    (name: 'uppercase'): IFilterUppercase; 
    (name: 'limitTo'): IFilterLimitTo; 
    (name: 'orderBy'): IFilterOrderBy; 
    /** 
    * Usage: 
    * $filter(name); 
    * 
    * @param name Name of the filter function to retrieve 
    */ 
    <T>(name: string): T; 
} 

this.$filter('modelFilter')。這意味着使用最後一條規則(即<T>(name: string): T;)。因此,this.$filter('modelFilter')ng.IFilterService的類型,TypeScript不知道有關您的ModelFilter的任何內容。

您可以通過添加第一個代碼清單中顯示的新界面來解決問題。

你說,原代碼在你的另一個項目中工作,但它似乎不太可能我,除非reference.ts以某種方式修改。

+0

我試過你的解決方案,但我得到完全相同的錯誤。僅供參考,使用grunt-ts創建reference .ts,其中包含對tsd.d.ts的引用,其中包含對angular.d.ts的引用,所以基本上reference.ts包含對應用程序中所有ts文件的引用以及絕對鍵入的文件。我已更新我的問題以顯示此內容。 – AngularBoy

+0

你可以將修改過的代碼發佈到pastebin嗎? –

+0

我使用TypeScript 1.6.2。無論如何,你可以從這裏https://pastee.org/5hfp代碼http://www.typescriptlang.org/Playground看到它的作品。 –

0

我只是想分享一個類似的例子,使用矩量庫來格式日期在控制器或前端。

export interface IMomentFilter extends ng.IFilterService { 
    (name: 'momentFilter'): (dateString: string, format: string) => string; 
} 

export class MomentFilter { 
    public static Factory() { 
     return function (dateString: string, format: string) { 
      return moment(dateString).format(format); 
     } 
    } 
} 

這是如何能夠在控制器中使用利用所述Ag-網格cellRenderer的格式化日期:

var columnDefs = [ 
{ 
    headerName: "Reported Date", 
    field: "reportedDate", 
    cellRenderer: function (params) 
    { 
     return $filter('momentFilter')(params.value, "MM/DD/YYYY"); 
    } 
}]; 

這是它如何在前端使用:

<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">Created Date: 
    <label class="field"> 
    <label class="field">{{vm.model.reportedDate| momentFilter:'MM/DD/YYYY' }}</label> 
    </label> 
</div> 

我希望這有助於。非常感謝原始帖子。我真的在摸索着使用IFilterService接口來獲得正確的語法。

1

如果您看到IFilterService的最後一行,那麼自定義過濾器有一個通用類型。

interface IFilterService { 
    (name: 'filter'): IFilterFilter; 
    (name: 'currency'): IFilterCurrency; 
    (name: 'number'): IFilterNumber; 
    (name: 'date'): IFilterDate; 
    (name: 'json'): IFilterJson; 
    (name: 'lowercase'): IFilterLowercase; 
    (name: 'uppercase'): IFilterUppercase; 
    (name: 'limitTo'): IFilterLimitTo; 
    (name: 'orderBy'): IFilterOrderBy; 
    /** 
    * Usage: 
    * $filter(name); 
    * 
    * @param name Name of the filter function to retrieve 
    */ 
    <T>(name: string): T; 
} 

由於錯誤提示,您的自定義過濾器沒有調用簽名。所以,你可以爲你的過濾器的接口,其中包括呼叫簽名:

export interface MyModelFilter { 
    (input: string): string; 
} 

然後當你打電話給你的過濾器,你可以使用IFilterService的通用型您的來電簽名屬性自定義過濾器

updateModels(make: string): void { 
    var test = this.$filter<MyModelFilter>('modelFilter')(make); 
} 
相關問題