TypeScript mit KnockoutJS

137

Gibt es ein Beispiel für die Verwendung von TypeScript mit KnockoutJS? Ich bin nur neugierig, wie sie zusammenarbeiten würden.

Bearbeiten

Hier ist was ich habe, scheint zu funktionieren

declare var ko: any;
declare var $: any;
class ViewModel {
    x = ko.observable(10);
    y = ko.observable(10);

}

$(() => {
    ko.applyBindings(new ViewModel());
});

Dies führt zu folgendem Javascript:

var ViewModel = (function () {
    function ViewModel() {
        this.x = ko.observable(10);
        this.y = ko.observable(10);
    }
    return ViewModel;
})();
$(function () {
    ko.applyBindings(new ViewModel());
});
CallumVass
quelle
6
Ich war etwas verwirrt von dem Schlüsselwort "declare", das in Verbindung mit "var" verwendet wurde, bis ich den Abschnitt über Umgebungsdeklarationen in der Spezifikation fand. Macht jetzt vollkommen Sinn: typescriptlang.org/Content/… .
Rex Miller
2
In Typescript 0.9 haben wir Generics, die Ihnen typisierte Observables geben : ko.observable<number>(10). Ich schrieb einen Blogpost mit einigen detaillierteren Informationen: ideasof.andersaberg.com/idea/12/…
Anders

Antworten:

108

Schauen Sie sich DefinitelyTyped an .

"Repository für TypeScript-Typdefinitionen für beliebte JavaScript-Bibliotheken"

George Mavritsakis
quelle
3
Dies mag eine dumme Frage sein, aber können Sie erklären, was genau eine TypeScript-Typdefinition ist / tut? Ist es nur so, dass Sie Bibliotheksfunktionen in einer mit TypeScript kompilierten Datei verwenden können, ohne dass sich der Compiler beschwert? Wenn dies der Fall ist, müssten Sie nicht auf die Definition in Ihrer Anwendung verweisen, nur wenn Sie die ts-Dateien kompilieren, richtig?
unbestreitbarrob
9
Das ist genau der Fall. Wenn Sie Ihren Typoskript-Code in den Editor schreiben würden, würden Sie die Definitionen nur zur Kompilierungszeit benötigen. Auf der anderen Seite ist einer der guten Punkte von Typoskript, dass es für die Intelligenz von Visual Studio (und anderen Editoren über Plugins) einfacher ist, Ihren Code zu verstehen, und es hilft Ihnen sehr bei der automatischen Vervollständigung und bei der Durchführung von Typ- und Fehlerprüfungen (viel mehr) als JavaScript). Aus diesem Grund verwenden wir Definitionsdateien für in JavaScript geschriebenen Code, um die Typoskriptprüfung zu ermöglichen. Natürlich können Sie libs als "any" deklarieren, aber das ist nicht gut. Hoffentlich habe ich geholfen!
George Mavritsakis
5
Beachten Sie, dass der Schlüssel darin besteht, /// <reference path="knockout-2.2.d.ts" />oben in Ihre .ts-Datei einzufügen, damit die Definitionen übernommen werden.
Aidan Ryan
Ich sehe nirgendwo in der Liste Knockout .... entfernt? gerührt?? frustriert
Jester
58

Ich habe diese kleine Schnittstelle erstellt, um statische Typen für Knockout zu erhalten:

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;
    };
}

Fügen Sie es in "Knockout.d.ts" ein und verweisen Sie es dann aus Ihren eigenen Dateien. Wie Sie sehen können, würde es stark von Generika profitieren (die gemäß den Spezifikationen kommen).

Ich habe nur ein paar Schnittstellen für ko.observable () erstellt, aber ko.computed () und ko.observableArray () können problemlos im selben Muster hinzugefügt werden. Update: Ich habe die Signaturen für subscribe () korrigiert und Beispiele für computed () und ObservableArray () hinzugefügt.

Fügen Sie dies oben hinzu, um es aus Ihrer eigenen Datei zu verwenden:

/// <reference path="./Knockout.d.ts" />
declare var ko: Knockout;
Sten L.
quelle
2
@JcFx: Anders erwähnte wahrscheinlich die Option, eine TypeScript-.ts-Datei zu nehmen und eine Schnittstellendeklarationsdatei .d.ts auszugeben. Es gibt keine Möglichkeit, normales untypisiertes JavaScript zu verwenden und die Typen auf magische Weise zu entdecken. Das Problem mit JS (das TypeScripts zu lösen versucht) ist, dass es für die Programmiererin keine Möglichkeit gibt, ihre Absicht zu erklären, dass eine Variable einem bestimmten Typ entsprechen soll. Wenn Sie x = 'hello'in JS sagen , wissen wir nicht, ob Sie es später in Ihrem Code sagen wollten x = 34. Hance können wir nichts über die Art von x schließen.
Sten L
@JcFx: Eigentlich haben Sie vielleicht Recht, dass einige eingeschränkte Typinformationen von einfachem JS abgeleitet werden könnten. Lassen Sie mich wissen, wie es geht, wenn Sie es versuchen!
Sten L
Typoskript fügt Generika hinzu.
Daniel A. White
6

An der Art und Weise, wie Knockout-Bindungen im Markup deklariert werden, würde sich nichts ändern. Wir würden jedoch die Intellisense-Güte erhalten, sobald die Schnittstellen für die Knockout-Bibliothek geschrieben sind. In dieser Hinsicht würde es genauso funktionieren wie das jquery-Beispiel , das eine Typoskriptdatei enthält, die Schnittstellen für die meisten jQuery-APIs enthält .

Ich denke, wenn Sie die beiden Variablendeklarationen für ko und $ loswerden, wird Ihr Code funktionieren. Diese verbergen die tatsächlichen Ko- und $ -Variablen, die beim Laden der Knockout- und JQuery-Skripte erstellt wurden.

Ich musste dies tun, um das Visual Studio-Vorlagenprojekt auf Knockout zu portieren:

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>
Jeremy Danyow
quelle
1
Postet
3

Ok, verwenden Sie einfach den folgenden Befehl, um die Knockout-Typen oder tds zu importieren.

npm install @types/knockout

Dadurch wird ein @ types-Verzeichnis im Verzeichnis node_modules Ihres Projekts erstellt, und die Definitionsdatei für den Index-Knockout-Typ befindet sich in einem Verzeichnis mit dem Namen knockout. Als nächstes durch einen dreifachen Schrägstrich auf die Typendatei. Dies bietet großartige IDE- und TypeScript-Funktionen.

/// <reference path="../node_modules/@types/knockout/index.d.ts" />

Verwenden Sie zum Schluss einfach eine declare-Anweisung, um die ko-Variable in den Gültigkeitsbereich zu bringen. Dies ist stark typisiert, also hallo Intellisense.

declare var ko: KnockoutStatic;

Jetzt können Sie KO genau wie in Ihren Javascript-Dateien verwenden.

Geben Sie hier die Bildbeschreibung ein

Hoffe das hilft.

SimperT
quelle