TypeScript с KnockoutJS

131

Есть ли образец использования 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());
});
  • 6
    Меня несколько смутило ключевое слово «объявлять», используемое вместе с «var», пока я не нашёл раздел о Ambient Declarations в спецификации. Имеет смысл сейчас: typescriptlang.org/Content/… .
  • 2
    В Typescript 0.9 у нас есть Generics, который дает вам типизированные наблюдаемые: ko.observable<number>(10) . Я написал пост в блоге с более подробной информацией: ideasof.andersaberg.com/idea/12/…
Показать ещё 1 комментарий
Теги:
knockout.js

6 ответов

99
Лучший ответ

Посмотрите DefinitelyTyped.

"TypeScript репозиторий определений типов для популярных библиотек JavaScript"

  • 3
    Это может быть глупый вопрос, но можете ли вы объяснить, что именно такое определение типа TypeScript? Это чисто для того, чтобы вы могли использовать библиотечные функции в скомпилированном TypeScript-файле без жалоб компилятора? Если это так, вам не нужно ссылаться на определение в вашем приложении, только когда вы компилируете файлы ts, правильно?
  • 8
    Это именно тот случай. Если бы вы писали свой машинописный код в блокноте, вам понадобились бы определения только во время компиляции. С другой стороны, одна из положительных сторон машинописного текста заключается в том, что для Visual Studio (и других редакторов с помощью плагинов) легче понимать ваш код, и это очень помогает вам при автозаполнении и выполнении проверки типов и ошибок (гораздо больше). чем JavaScript). Вот почему мы используем файлы определений для кода, написанного на JavaScript, чтобы обеспечить проверку типов машинописи. Конечно, вы можете объявить libs как «любой», но это не хорошо. Надеюсь, я помог!
Показать ещё 1 комментарий
56

Я сделал этот небольшой интерфейс для получения статических типов для 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() и добавил примеры вычисляемых() и наблюдаемыхArray().

Чтобы использовать его из собственного файла, добавьте его вверху:

/// <reference path="./Knockout.d.ts" />
declare var ko: Knockout;
  • 1
    Knockout JS Decleration file для Typescript - gist.github.com/3833509
  • 2
    @JcFx: То, на что ссылался Андерс, было, вероятно, возможностью взять файл TypeScript .ts и вывести файл объявления интерфейса .d.ts. Нет никакого способа взять обычный нетипизированный JavaScript и волшебным образом обнаружить типы. Проблема с JS (которую пытается решить TypeScripts) состоит в том, что у программиста нет возможности заявить о своем намерении, чтобы переменная соответствовала определенному типу. Когда вы говорите x = 'hello' в JS, мы не знаем, намеревались ли вы где-нибудь позже в своем коде сказать x = 34 . Поэтому мы ничего не можем сказать о типе x.
Показать ещё 2 комментария
14

Попробуйте реализовать декларации интерфейса TypeScript (с простым примером)
https://github.com/sv01a/TypeScript-Knockoutjs

6

Ничто не изменилось бы с точки зрения того, как объявлены нокаут-привязки в разметке, однако мы получим доброту intellisense, как только интерфейсы будут записаны для библиотеки нокаутов. В этом отношении он будет работать так же, как jquery Sample, который содержит typescript файл, содержащий интерфейсы для большей части jQuery апи.

Я думаю, что если вы избавитесь от двух объявлений переменных для ko и $, ваш код будет работать. Они скрывают фактические переменные ko и $, которые были созданы при загрузке сценариев нокаута и jquery.

Мне пришлось сделать это, чтобы портировать проект шаблона визуальной студии для нокаута:

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="/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>
  • 0
    Хороший вопрос относительно интерфейсов!
  • 1
    Разве не публиковать в ко всем конструкторам вид излишнего
2

Я использую https://www.nuget.org/packages/knockout.editables.TypeScript.DefinitelyTyped/ и у него есть все интерфейсы для Knockout.

0

Хорошо, просто используйте следующую команду, чтобы импортировать типы нокаутов или tds.

npm install @types/knockout

Это создаст каталог @types в каталоге проектов node_modules, а файл определения типа нокаута индекса будет находиться в каталоге с именем нокаут. Затем по ссылке с тройным слэшем в файл типов. Это даст отличные функции IDE и TypeScript.

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

Наконец, просто используйте оператор declare для приведения переменной ko в область видимости. Это строго типизировано так приветливо intellisense.

declare var ko: KnockoutStatic;

Итак, теперь вы можете использовать KO так же, как в ваших файлах javascript.

Изображение 3479

Надеюсь, что это поможет.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню