2016-06-30 4 views
1

this best practices guideの後にタイプスクリプトを覚えようとしていますが、ここで何か不足しているような気がします。角度1.5でコンポーネント関数をバインドするときに、タイプスクリプトを利用するにはどうすればよいですか?

ここには、typescriptで書かれた作業用コードがあります。私に迷惑をかけるのは、実際にここでタイプスクリプトを利用するような気がしないということです。関数のシグネチャを変更する場所があれば、コンパイラは気付かないでしょう。

私に説明してみましょう:一部のコンポーネントは、物事のリストである

// thing.interface.ts 
export interface IThing { 
    name: string, 
    id: number, 
} 

まずさんは "もの" を定義してみましょう

// listOfThings.component.ts 
import ListOfThingCtrl from './listOfThings.controller.ts' 
const listOfThings = { 
    bindings: { 
    things: '<', 
    }, 
    controller: ListOfThingCtrl, 
    template: ` 
    <p> list of things: <p> 
    <ul> 
    <li ng-repeat="thing in $ctrl.things"> 
     <thing thing="thing" on-delete="$ctrl.deleteThing($event)"></thing> 
    </li> 
    </ul> 
    `, 
} 

そして、我々はthingコンポーネントがあります

import ThingCtrl from './thing.controller.ts' 

const thing = { 
    bindings: { 
    onDelete: '&', 
    thing: '<', 
    }, 
    controller: ThingCtrl, 
    template: ` 
    <p> 
    thing: {{$ctrl.thing.name}} 
    <a ng-click='$ctrl.deleteThing()' > 
     Delete me 
    </a> 
    </p> 
    `, 
} 

だからとても良い。

今度は、コントローラを定義してみましょう:

//listOfThings.controller.js 
import {IThing} from './thing.interface.ts' 

export default class ListOfThingCtrl { 
    private things: Array<IThing> 

    public deleteThing (thing: IThing): void { 
    const i = this.things.map(t => t.id).indexOf(thing.id) 
    if (i > -1) { 
     this.things.splice(i, 1) 
    } 
    } 
} 


// thing.controller.js 
import {IThing} from './thing.interface.ts' 

export default class ThingCtrl { 
    private thing: IThing 

    // This line looks dangerous to me : this should be imported, not declared ! 
    private onDelete: (e: {$event: IThing}) => void // What now if the bounded function were to change ? 

    public deleteThing(): void { 
    this.onDelete({$event: this.thing}) 
    } 
} 

このコードは、「作品」:それは文句なしでコンパイル、ロード、およびいくつかをクリックすると、実際には、コントローラの一覧から「もの」を削除します「私は削除」 "物事"

私にとって気になること:このコードではonDelete機能をthingコンポーネントに注入しますが、実際の署名は絶対に注入しません。

誰かがdeleteThing機能を変更した場合、 deleteThing(thing: IThing)の代わりにdeleteThing(thingId: number)としましょう。その後、は何も動作しなくなりましたが、コンパイラはちょうど丁度をコンパイルするでしょう。

deleteThingのシグネチャは変更されましたが、onDeleteは実行時には失敗することを知らずに古い引数で呼び出すことができます。

私は非常に新しいタイプコピーですが、私はおそらくここで重要なものを欠いているでしょう。

角度成分を使って関数シグネチャを渡すことを可能にするベストプラクティスはありますか?

読んでいただきありがとうございます!

まずは、ListOfThingsコンポーネントテンプレートに若干の修正を作ってみよう:

答えて

0

は私が私には満足のいくようだ何かを考え出し

<thing thing="thing" on-delete="$ctrl.deleteThing({$event})"></thing>

(代わりにdeleteThing($event)の)両方onDeleteをするようにし、 deleteThingは全く同じ署名を持っています。

thing.interface.jsの関数インターフェースを宣言:

export interface IDeleteThing { 
     (e: {$event: {thing: IThing}}): void 
    } 

今両方コントローラインターフェイスをインポートし、それを使用することができ:

// listOfThings.controller.ts 
import {IThing, IDeleteThing} from './thing.interface.ts' 

export default class ListOfThingCtrl { 
    private things: Array<IThing> 

    public deleteThing: IDeleteThing = ({$event}) => { 
    const i = this.things.map(t => t.id).indexOf($event.thing.id) 
    if (i > -1) { 
     this.things.splice(i, 1) 
    } 
    } 
} 

// thing.controller.ts 
import {IThing, IDeleteThing} from './thing.interface.ts' 

export default class ThingCtrl { 
    private thing: IThing 
    private onDelete: IDeleteThing 

    public deleteThing(): void { 
    this.onDelete({$event: {thing: this.thing}}) 
    } 
} 

を署名は今や、共有モジュールとの間の任意の矛盾する定義されたように2つのコントローラがコンパイラによって検出されるようになります。\ o/

関連する問題