TypeScript con KnockoutJS


137

C'è qualche esempio dell'uso di TypeScript con KnockoutJS? Sono solo curioso di sapere come avrebbero lavorato insieme?

modificare

Ecco quello che ho, sembra funzionare

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

}

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

Questo genera nel seguente Javascript:

var ViewModel = (function () {
    function ViewModel() {
        this.x = ko.observable(10);
        this.y = ko.observable(10);
    }
    return ViewModel;
})();
$(function () {
    ko.applyBindings(new ViewModel());
});

6
Sono stato un po 'confuso dalla parola chiave "declare" utilizzata insieme a "var" fino a quando non ho trovato la sezione sulle dichiarazioni ambientali nelle specifiche. Ha perfettamente senso ora: typescriptlang.org/Content/… .
Rex Miller,

2
In tipografico 0.9 abbiamo Generics, che consente digitato osservabili: ko.observable<number>(10). Ho scritto un post sul blog con alcune informazioni più dettagliate: ideasof.andersaberg.com/idea/12/…
Anders,

Risposte:


108

Guarda DefinitelyTyped .

"Repository di definizioni del tipo TypeScript per le più diffuse librerie JavaScript"


3
Questa può essere una domanda stupida, ma puoi spiegare che cosa è / fa esattamente una definizione di tipo TypeScript? È puramente possibile utilizzare le funzioni di libreria in un file compilato TypeScript senza che il compilatore si lamenti? In tal caso, non dovresti fare riferimento alla definizione nella tua applicazione, proprio quando compili i file ts, giusto?
Innegabilmente, il

9
Questo è esattamente il caso. Se scrivessi il tuo codice dattiloscritto nel blocco note, avresti bisogno solo delle definizioni al momento della compilazione. D'altra parte, uno dei punti positivi del dattiloscritto è che è più facile per l'intelligence di Visual Studio (e altri editor tramite plug-in) comprendere il tuo codice e ti aiuta molto con il completamento automatico ed eseguire il controllo di tipo ed errore (molto altro di JavaScript). Ecco perché utilizziamo i file di definizione per il codice scritto in JavaScript in modo da fornire il controllo del tipo di dattiloscritto. Ovviamente potresti dichiarare le librerie come "qualsiasi", ma non va bene. Spero di averti aiutato!
George Mavritsakis,

5
Nota che la chiave è aggiungere /// <reference path="knockout-2.2.d.ts" />all'inizio del tuo file .ts in modo che raccolga le definizioni.
Aidan Ryan,

Non vedo knockout da nessuna parte nell'elenco .... rimosso ?? mosso?? frustrato
Giullare

58

Ho creato questa piccola interfaccia per ottenere tipi statici per 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;
    };
}

Inseriscilo in "Knockout.d.ts" e fai riferimento ai tuoi file. Come puoi vedere, trarrebbe grandi benefici dai generici (che stanno arrivando secondo le specifiche).

Ho creato solo alcune interfacce per ko.observable (), ma ko.computed () e ko.observableArray () possono essere facilmente aggiunti nello stesso modello. Aggiornamento: ho corretto le firme per iscriviti () e ho aggiunto esempi di computed () e observableArray ().

Per utilizzare dal tuo file, aggiungi questo in alto:

/// <reference path="./Knockout.d.ts" />
declare var ko: Knockout;

2
@JcFx: Ciò a cui Anders si riferiva era probabilmente l'opzione per prendere un file .ts TypeScript e generare un file di dichiarazione dell'interfaccia .d.ts. Non c'è modo di prendere regolarmente JavaScript non tipizzato e scoprire magicamente i tipi. Il problema con JS (che TypeScripts tenta di risolvere) è che non c'è modo per il programmatore di dichiarare la sua intenzione che una variabile debba essere conforme a un determinato tipo. Quando dici x = 'hello'in JS, non sappiamo se hai intenzione di dire da qualche parte in seguito nel tuo codice x = 34. Quindi non possiamo dedurre nulla sul tipo di x.
Sten L

@JcFx: in realtà, potresti avere ragione sul fatto che alcune informazioni di tipo limitato potrebbero essere derivate da JS semplice. Fammi sapere come va quando ci provi!
Sten L

dattiloscritto aggiunge generici.
Daniel A. White,


6

Nulla cambierebbe in termini di come vengono dichiarati i vincoli a eliminazione diretta nel markup, tuttavia otterremmo la bontà intellettuale una volta che le interfacce sono state scritte per la libreria a eliminazione diretta. A questo proposito funzionerebbe proprio come l' esempio jquery , che ha un file dattiloscritto contenente interfacce per la maggior parte dell'API jQuery .

Penso che se ti sbarazzi delle due dichiarazioni variabili per ko e $ il tuo codice funzionerà. Questi nascondono le variabili ko e $ che sono state create quando sono stati caricati gli script knockout e jquery.

Ho dovuto fare questo per portare il progetto del modello di Visual Studio su knockout:

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>

1
Non sta postando in ko per ogni tipo di costruttore di overkill
Simon_Weaver

3

Ok quindi usa il seguente comando per importare i tipi knockout o tds.

npm install @types/knockout

Ciò creerà una directory @types nella directory node_modules dei progetti e il file di definizione del tipo knockout dell'indice sarà in una directory chiamata knockout. Successivamente, tramite un riferimento a tre barre al file types. Ciò fornirà grandi funzionalità IDE e TypeScript.

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

Infine, basta usare un'istruzione declare per portare la variabile ko nell'ambito. Questo è fortemente tipizzato, quindi ciao intellisense.

declare var ko: KnockoutStatic;

Quindi ora puoi usare KO proprio come nei tuoi file javascript.

inserisci qui la descrizione dell'immagine

Spero che questo ti aiuti.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.