我想为来自库的现有类添加一些方法。
已知某些基本类型,例如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);
}
}
答案 0 :(得分: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});
}
这种方法可以在其他类上添加扩展方法,希望这能帮到别人。
答案 1 :(得分: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
}
使用打字稿时不需要原型。
修改强>
我没试过,如果这样可行,但是你可以传递自己的扩展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
中的步骤进行操作