2017-07-31 41 views
2

我想向來自庫的已存在類添加一些方法。在Typescript中,爲來自庫的類創建擴展方法

已知一些基本類型,如String,Element可以通過interface擴展並添加它的prototype

interface String { 
extFunc():Function; 
} 

String.prototype.extFunc = function() { 
    //blabla 
}; 

"a".extFunc(); 

我也找到了添加擴展方法Observable<T>的方法。

declare module 'rxjs/Observable' { 
    interface Observable<T> { 
    foo: String; 
    } 
} 
Observable.prototype.foo= "bar"; 
console.log(Observable.of("a").foo); 

但是,當我試圖做同樣的事情給NavController(從離子的LIB),它將覆蓋整個NavController給我申報的接口。

declare module 'ionic-angular' { 
    interface NavController { 
    replace(page: Page): Promise<any>; 
    } 
} 
navCtrl.replace(...); //ok 
navCtrl.push(...); //original function => "not exist" 

有沒有人知道什麼是擴展方法添加到這些類的最佳方式?謝謝〜

編輯: 有實際的代碼

import {Component} from '@angular/core'; 
import {NavController} from 'ionic-angular'; 

import {GuidePage} from '../guide/guide.component'; 

@Component({ 
    selector: 'page-home', 
    templateUrl: 'home.component.html' 
}) 
export class HomePage { 
    pageName = "home"; 

    // navCtrl is come from angular2's Dependency Injection, 
    // it may not suitable to extend NavController 
    constructor(public navCtrl: NavController) {} 

    gotoGuide(): void { 
    //wanna replace this 
    this.navCtrl.push(GuidePage).then(() => { 
     let index = this.navCtrl.getActive().index; 
     this.navCtrl.remove(index - 1); 
    }); 

    //with this custom extension method 
    //this.navCtrl.replace(GuidePage); 
    } 
} 

回答

1

好吧,我參考this answer和解決我用下面的代碼問題。

polyfill.ts

import {Page} from 'ionic-angular/navigation/nav-util'; 
// the class we wanna create extension method 
import {NavController} from 'ionic-angular/navigation/nav-controller'; 
// ionic provide this as NavController 
import {NavControllerBase} from 'ionic-angular/navigation/nav-controller-base'; 

// add extension method on both class via interface 
declare module "ionic-angular/navigation/nav-controller" { 
    interface NavController { 
    // replacePage?: typeof replacePage; 
    replacePage(page: Page, data?: any); 
    } 
} 
declare module "ionic-angular/navigation/nav-controller-base" { 
    interface NavControllerBase { 
    // replacePage?: typeof replacePage; 
    replacePage(page: Page, data?: any); 
    } 
} 

// define extension method 
function replacePage(this: NavController, page: Page, data?: any): Promise<any> { 
    return this.push(page, data).then(() => { 
    let index = this.getActive().index; 
    this.remove(index - 1); 
    }); 
} 

// finally add this function to the class that ionic provide 
NavControllerBase.prototype.replacePage = replacePage; 

用法:

constructor(private navCtrl: NavController) 
foo(){ 
    this.navCtrl.replacePage(HomePage, {nextPage: OtherPage}); 
} 

這種方式在其他類中添加擴展方法,希望以後這種幫助別人。

0

你的問題是如何擴展一個類,但你的代碼顯示接口。

如何從庫擴展一個類:

class LibraryThing { 
    // this is a class from a library 
    doSomething(){ 
    } 
} 

class MyThing extends LibraryThing { 
    // here you can add your own methods to the existing class 
    doMyThing(){ 
    } 
} 

現在,您可以創建一個將所有的庫方法和你自己的方法MyThing實例:

let t = new MyThing(); 
t.doSomething(); 
t.doMyThing(); 

如果你想使用接口,你可以簡單地實現它們。您可以實現現有的庫接口並使用自己的接口對其進行補充

interface LibraryInterface {} 
interface MyOwnInterface {} 

class CoolThing implements LibraryInterface, MyOwnInterface { 
    // this class uses methods from the library interface and your own 
} 

使用typescript時,不需要原型。

編輯

如果這個工程,但而不是傳遞navcontroller在構造函數中我還沒有嘗試過,你可以通過你自己的類,它擴展navcontroller。

import {Component} from '@angular/core'; 

import {CustomController} from '../mystuff/customcontroller';  
import {GuidePage} from '../guide/guide.component'; 

@Component({ 
    selector: 'page-home', 
    templateUrl: 'home.component.html' 
}) 
export class HomePage { 
    pageName = "home"; 

    // here we receive our own CustomController 
    constructor(public navCtrl: CustomController) {} 

    gotoGuide(): void { 
    this.navCtrl.myOwnCustomStuff(); 
    } 
} 

在CustomController可以導入Navcontroller並且將其擴展:

import { Injectable } from '@angular/core' 
import {NavController} from 'ionic-angular' 

@injectable() 
export class CustomController extends NavController { 
} 

,如果這是允許的離子成分,雖然我沒有測試過!

您也可以註冊自己的新的注射作爲角DI供應商,請按照下列步驟在your link

+0

感謝您的回答,但我想添加方法的類來自於angular2的依賴注入,換言之,它來自構造函數()。看到更多的細節。 https://angular.io/guide/dependency-injection#injectable –

+0

也許你可以用你的實際代碼來澄清你的問題,包括依賴注入。 – Kokodoko

+0

好的!我發佈了我的實際代碼,感謝您的建議。 –