带有 KnockoutJS 的 TypeScript
Posted
技术标签:
【中文标题】带有 KnockoutJS 的 TypeScript【英文标题】:TypeScript with KnockoutJS 【发布时间】:2012-09-23 06:32:39 【问题描述】:有没有使用 TypeScript 和 KnockoutJS 的示例?我只是好奇他们将如何合作?
编辑
这是我所拥有的,似乎可以工作
declare var ko: any;
declare var $: any;
class ViewModel
x = ko.observable(10);
y = ko.observable(10);
$(() =>
ko.applyBindings(new ViewModel());
);
这会生成以下 javascript:
var ViewModel = (function ()
function ViewModel()
this.x = ko.observable(10);
this.y = ko.observable(10);
return ViewModel;
)();
$(function ()
ko.applyBindings(new ViewModel());
);
【问题讨论】:
我对与“var”结合使用的“declare”关键字感到有些困惑,直到我在规范中找到关于环境声明的部分。现在很有意义:typescriptlang.org/Content/…. 在 Typescript 0.9 中,我们有泛型,它为您提供输入的 observables:ko.observable<number>(10)
。我写了一篇博文,提供了一些更详细的信息:ideasof.andersaberg.com/idea/12/…
【参考方案1】:
看看DefinitelyTyped。
“流行 JavaScript 库的 TypeScript 类型定义存储库”
【讨论】:
这可能是一个愚蠢的问题,但你能解释一下 TypeScript 类型定义到底是什么/做什么吗?纯粹是为了让您可以在 TypeScript 编译的文件中使用库函数而编译器不会抱怨吗?如果是这种情况,您不需要在应用程序中引用定义,只需在编译 ts 文件时,对吗? 正是如此。如果您在记事本中编写打字稿代码,则只需要在编译时定义。另一方面,打字稿的一个优点是它更容易让视觉工作室(和其他通过插件的编辑器)智能理解你的代码,它可以帮助你自动完成和执行类型和错误检查(更多比 JavaScript)。这就是为什么我们使用 JavaScript 编写的代码的定义文件来提供 typescript 类型检查。当然,您可以将库声明为“任何”,但这并不好。希望我有所帮助! 请注意,关键是将/// <reference path="knockout-2.2.d.ts" />
添加到 .ts 文件的顶部,以便它获取定义。
我在列表中的任何地方都看不到淘汰赛....已删除??搬家了??沮丧【参考方案2】:
我制作了这个小接口来获取 Knockout 的静态类型:
interface ObservableNumber
(newValue: number): void;
(): number;
subscribe: (callback: (newValue: number) => void) => void;
interface ObservableString
(newValue: string): void;
(): string;
subscribe: (callback: (newValue: string) => void) => void;
interface ObservableBool
(newValue: bool): void;
(): bool;
subscribe: (callback: (newValue: bool) => void) => void;
interface ObservableAny
(newValue: any): void;
(): any;
subscribe: (callback: (newValue: any) => void) => void;
interface ObservableStringArray
(newValue: string[]): void;
(): string[];
remove: (value: String) => void;
removeAll: () => void;
push: (value: string) => void;
indexOf: (value: string) => number;
interface ObservableAnyArray
(newValue: any[]): void;
(): any[];
remove: (value: any) => void;
removeAll: () => void;
push: (value: any) => void;
interface Computed
(): any;
interface Knockout
observable:
(value: number): ObservableNumber;
(value: string): ObservableString;
(value: bool): ObservableBool;
(value: any): ObservableAny;
;
observableArray:
(value: string[]): ObservableStringArray;
(value: any[]): ObservableAnyArray;
;
computed:
(func: () => any): Computed;
;
将其放入“Knockout.d.ts”中,然后从您自己的文件中引用它。如您所见,它将从泛型(根据规范提供)中受益匪浅。
我只为 ko.observable() 做了几个接口,但是 ko.computed() 和 ko.observableArray() 可以很容易地添加到相同的模式中。 更新:我修复了 subscribe() 的签名并添加了 computed() 和 observableArray() 的示例。
要从您自己的文件中使用,请在顶部添加:
/// <reference path="./Knockout.d.ts" />
declare var ko: Knockout;
【讨论】:
@JcFx:Anders 提到的可能是采用 TypeScript .ts 文件并输出接口声明文件 .d.ts 的选项。没有办法使用常规的无类型 JavaScript 并神奇地发现类型。 JS 的问题(TypeScripts 试图解决的)是程序员无法声明她的意图,即变量应该符合特定类型。当您在 JS 中说x = 'hello'
时,我们不知道您是否打算稍后在代码中的某个地方说 x = 34
。我们无法推断出 x 的类型。
@JcFx:实际上,您可能是对的,一些有限的类型信息可以从纯 JS 派生。尝试时告诉我结果如何!
typescript 正在添加泛型。【参考方案3】:
试试我的TypeScript接口声明的实现(附简单例子)https://github.com/sv01a/TypeScript-Knockoutjs
【讨论】:
【参考方案4】:在标记中声明淘汰绑定的方式方面没有任何改变,但是一旦为淘汰库编写接口,我们就会获得智能感知优势。在这方面,它就像jquery Sample 一样工作,它有一个typescript file containing interfaces for most of the jQuery api。
我认为如果你去掉 ko 和 $ 的两个变量声明,你的代码就可以工作了。这些隐藏了在敲除和 jquery 脚本加载时创建的实际 ko 和 $ 变量。
我必须这样做才能将 Visual Studio 模板项目移植到淘汰赛:
app.ts:
class GreeterViewModel
timerToken: number;
utcTime: any;
constructor (ko: any)
this.utcTime = ko.observable(new Date().toUTCString());
this.start();
start()
this.timerToken = setInterval(() => this.utcTime(new Date().toUTCString()), 500);
window.onload = () =>
// get a ref to the ko global
var w: any;
w = window;
var myKO: any;
myKO = w.ko;
var el = document.getElementById('content');
myKO.applyBindings(new GreeterViewModel(myKO), el);
;
default.htm:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>TypeScript HTML App</title>
<link rel="stylesheet" href="app.css" type="text/css" />
<script src="Scripts/knockout-2.1.0.debug.js" type="text/javascript"></script>
<script src="app.js"></script>
</head>
<body>
<h1>TypeScript HTML App</h1>
<div id="content" data-bind="text: utcTime" />
</body>
</html>
【讨论】:
不是在 ko 中发布给每个构造函数的那种矫枉过正【参考方案5】:好的,只需使用以下命令导入敲除类型或 tds。
npm install @types/knockout
这将在您的项目 node_modules 目录中创建一个@types 目录,并且索引敲除类型定义文件将位于名为敲除的目录中。 接下来,通过对类型文件的三斜杠引用。这将提供出色的 IDE 和 TypeScript 功能。
/// <reference path="../node_modules/@types/knockout/index.d.ts" />
最后,只需使用声明语句将 ko 变量带入作用域。这是强类型的,所以你好智能感知。
declare var ko: KnockoutStatic;
所以现在您可以像在您的 javascript 文件中一样使用 KO。
希望这会有所帮助。
【讨论】:
这对 2021 年的我来说是完美的。在利用 npm 的同时将 Typescript 与现有的旧 Javascript 混合。谢谢。【参考方案6】:我正在使用https://www.nuget.org/packages/knockout.editables.TypeScript.DefinitelyTyped/ 并且它具有用于 Knockout 的所有接口。
【讨论】:
以上是关于带有 KnockoutJS 的 TypeScript的主要内容,如果未能解决你的问题,请参考以下文章
带有 jQuery UI 可排序的 Knockoutjs
带有模板和 foreach 的 KnockoutJS observableArray