我最近开始在documention之后用NativeScript制作一个插件。我使用src文件夹中的npm run demo.ios
进行了一些成功的运行。
但是,当开始构建我打算使用的实际插件时-遇到以下错误:
file:///node_modules/tns-core-modules/ui/builder/builder.js:179:0 JS错误错误:从XML构建UI。 @ app-root.xml:1:1 未定义不是对象(正在评估“ b.prototype”)
我已经在我试图从演示应用程序调用的ViewBase
文件中的myplugin.common.ts
上建立了扩展方法
我认为问题可能出在index.d.ts
上。根据文档,myplugin.ios.d.ts
和myplugin.android.d.ts
文件应复制到此处或手动定义。我正尝试在其中复制myplugin.common.d.ts
文件内容。那有效吗?
我还注意到,两次运行似乎都是不必要的-因为第一次运行会生成...d.ts.
,然后必须将其中的内容复制到index.d.ts
中。
一些代码...
myplugin.common.ts
declare module "tns-core-modules/ui/core/view-base/view-base" {
interface ViewBase {
myExenstionMethod(myNumber: number): void;
}
}
ViewBase.prototype.myExenstionMethod = function(myNumber: number) {
console.log("myNumber: " + myNumber);
}
和index.d.ts
(从myplugin.common.d.ts
复制):
declare module "tns-core-modules/ui/core/view-base/view-base" {
interface ViewBase {
myExenstionMethod(myNumber: number): void;
}
}
它在演示项目中显示:
错误来自简单地从我的演示项目中的插件中导入扩展方法:
import "nativescript-myplugin";
注意
我创建了一个新的插件项目-仅添加了扩展方法并且它起作用了。因此,原始插件项目中还有其他导致错误的原因。无需在declare module
中添加index.d.ts
。
再次点击
具有与以前相同的错误-从myplugin.common.ts
内部实例化myplugin.ios.ts / myplugin.android.ts-myplugin类时。我最初考虑要创建一个平台特定的单例实例以在.common.ts
中进行交互-但这似乎行不通?
import { Gestures as iOSGestures} from "./gestures.ios";
import {Gestures as AndroidGestures} from "./gestures.android";
export abstract class Common extends Observable {
private static _instance = null;
static instance(os: string): Common {
if(Common._instance == null) {
/* crash from instantiating iOSGestures or AndroidGestures */
this._instance = os == "iOS" ? new iOSGestures() : new AndroidGestures();
}
return Common._instance;
}
abstract _attach(viewBase: ViewBase, gesture: string): void;
}
奇怪的是,从未从任何地方调用过该特定代码。注释掉这一行,我可以通过仅包含包含实例化的无效代码来创建该错误:
// still inside .common.ts
import { Gestures } from "./gestures.android";
const object = {
methodInFile() {
const g = new Gestures() // <--
}
}
这是android.ts:
export class Gestures extends Common {
_attach(viewBase: ViewBase, gesture: string): void {
console.log("_attach android");
if(gesture == touch.down) {
}
}
}
可能与index.d.ts有冲突?
import { Common } from './gestures.common';
export declare class Gestures extends Common {
// define your typings manually
// or..
// take the ios or android .d.ts files and copy/paste them here
}
这是我第一次尝试构建插件NativeScript-因此我可能设置的东西完全错误。我希望将插件作为扩展方法提供给ViewBase
-并且common.ts中定义的扩展方法会成功调用。
// inside common.ts
export class Gestures extends Common {
_attach(): void {
console.log("_attach ios");
}
}
const object = {
methodInFile() {
const g = new Gestures() // <--
}
}
...有效。
但是当从另一个文件导入类时,具有new Gestures()
-会导致崩溃。创建新文件-ios.common.ts
均无效。因此,可能是npm run demo.ios
在生成时生成了错误的js文件吗?我还完全删除了index.d.ts
的内容-这样就不会引起错误。
为common.ts
提供一个接口-在.ios.ts
和android.ts
中实现。我遇到了一个新错误;
file:///app/home/home-page.ts:17:27 JS错误TypeError:page.addGestureHandler不是函数。 (在'page.addGestureHandler(“ hello”)'中,'page.addGestureHandler'未定义)
到目前为止,我的结论是,我不能将Common作为抽象类或接口-将ios.ts
和android.ts
实例化为单例。扩展抽象Common或实现接口Common的类必须与(common.ts)在同一文件中。 这可能与我使用扩展方法作为插件的入口点有关。
答案 0 :(得分:1)
TypeScript声明temp.txt
仅出于对IDE的IntelliSense支持的考虑。因此,只要导出要公开的权限定义,就没有所谓的有效或无效。大多数插件只会导出(*.d.ts)
,通常会暴露index.d.ts
中的所有内容。
更新:
为了防止生成*-common.ts
和.d.ts
文件,您需要将.js.map
中的declaration
和sourceMap
标志设置为src/tsconfig.json
。 / p>
您无法避免使用false
文件,这是使用TypeScript编译器(将TS转换为JS)的唯一原因。在发布插件或在演示应用程序中使用插件时,.js
文件是实际使用的文件。
之间,如果没有进行.js
调试,对您来说可能会很困难。
答案 1 :(得分:0)
我终于设法以正确且令人满意的方式设置了插件
两个要点是(如果使用扩展方法作为入口点):
declare module "tns-core-modules/ui/core/view-base" {
interface ViewBase {
addGestureHandler(gesture: string): void;
}
}
ViewBase.prototype.addGestureHandler = function(gesture: string) {
console.log("addGestureHandler: " + gesture);
// then calling platform specific singleton
}
...必须在myplugin.common.ts
的单独文件中定义。我称之为myplugin.ts
。
此设置也是如此。 myplugin.ios.ts
和myplugin.android.ts
必须删除。创建新文件:ios.impl.ts
和android.impl.ts
。然后common.ts
最终包含抽象类或接口。
因此在演示应用程序home-page.ts中,插件的用法如下:
import "nativescript-gestures"; // available only by having a common.ts file src folder in the plugin
import { NavigatedData, Page } from "tns-core-modules/ui/page";
import { HomeViewModel } from "./home-view-model";
export function onNavigatingTo(args: NavigatedData) {
const page = <Page>args.object;
page.bindingContext = new HomeViewModel();
page.addGestureHandler("hello"); // <-- addGestureHandler extension method
}