Я разделил свои модели просмотра на классы с помощью машинописного текста.
Теперь в моем Bootstraper я импортирую их все так:
import dl = module("DataLayer");
import vm1 = module("AppBarViewModel");
import vm2 = module("Nav2ViewModelCommander");
import vm3 = module("IdentityViewModel");
Невозможно ли их собрать в одном пространстве имен? Я использую requirejs, и мои viewmodels выглядят примерно так, когда компилируются в js.
define(["require", "exports"], function(require, exports) {
var AppBarViewModel = (function () {
function AppBarViewModel() {
this.visible = ko.observable(true);
this.buttons = ko.observableArray([]);
this.enableContext = ko.observable(true);
this.canClose = ko.computed(function () {
var k = ko.utils.arrayFirst(this.buttons(), function (b) {
return b.blockHide && b.blockHide == true;
});
return k == null;
});
}
AppBarViewModel.prototype.addButton = function (data) {
this.buttons.push(data);
this.visible(data.blockHide && data.blockHide == true);
};
AppBarViewModel.prototype.removeButton = function (data) {
this.buttons.remove(data);
this.visible(!this.canClose());
};
return AppBarViewModel;
})();
exports.AppBarViewModel = AppBarViewModel;
})
из
///<reference path="../knockout.d.ts" />
///<reference path="../require.d.ts" />
declare var ko: any;
export class AppBarViewModel {
visible = ko.observable(true);
buttons = ko.observableArray([]);
enableContext = ko.observable(true);
addButton(data) {
this.buttons.push(data);
this.visible(data.blockHide && data.blockHide == true);
}
removeButton(data) {
this.buttons.remove(data);
this.visible(!this.canClose());
}
canClose = ko.computed(function () {
//var buttons = self.buttons();
//ko.utils.arrayForEach(self.buttons(), function () { return });
var k = ko.utils.arrayFirst(this.buttons(), function (b) { return b.blockHide && b.blockHide == true });
return k == null;
});
constructor() {
}
}
Ага. Поместите viewmodels внутри того же модуля и импортируйте этот модуль.
В настоящее время вы создаете новый модуль для каждой модели viewmodel/class.
Обновление не работает см. Обновление 2 Если вы хотите, чтобы все еще есть несколько файлов для модулей, вы можете объединить их в один с компилятором типов:
tsc AppBarViewModel.ts IdentityViewModel.ts
Затем, предполагая, что файлы имеют один и тот же модуль "ViewModels" внутри них, вы можете импортировать их с помощью:
import vms = module("ViewModels");
Обновление 2 Слияние внешних модулей в настоящее время не поддерживается: https://typescript.codeplex.com/discussions/430782
Кроме того, на ваш вопрос о внешних модулях в одном файле. Внешние модули предполагают, что вы используете загрузчик модуля. В этом случае вы хотите, чтобы ваши модули были встроены в отдельные исходные файлы, чтобы их можно было загрузить через загрузчик модуля. Построение всех модулей в один.js файл противоречит тому, как работают эти инструменты.
Я мог видеть, что хочу создавать внешние модули из нескольких исходных файлов, хотя мы в настоящее время не поддерживаем это и, возможно, это хороший запрос функции для трекера ошибок, если он уже не существует
Проголосуйте за эту функцию здесь: https://typescript.codeplex.com/workitem/759
Я сделал, чтобы отключить поддержку AMD в машинописном тексте и вместо этого использовать пакет WebEssentials JS для создания единого экспорта для requireJS. Для этого у меня есть "_prebundle.fragment.js" и "_postbundle.fragment.js" и весь скомпилированный код TS между ними:
<file>/js/_prebundle.fragment.js</file>
<file>/js/file1.js</file>
<file>/js/file2.js</file>
<file>/js/file3.js</file>
<file>/js/_postbundle.fragment.js</file>
Это создает следующее:
///#source 1 1 /js/_prebundle.fragment.js
// START _PREBUNDLE.FRAGMENT >>
(function(factory){
// Support module loading scenarios
if (typeof define === 'function' && define.amd){
// AMD Anonymous Module
define(['jquery', 'ga', 'knockout', 'sammy'], factory);
} else {
// No module loader (plain <script> tag) - put directly in global namespace
var global = (window || this);
global.ma = factory(bootstrap, jQuery, qa, ko, sammy);
}
})(function($, ga, ko, sammy){
if (!$) throw new Error('JQuery is a pre-requisite and must be loaded for this component.');
if (!ga) throw new Error('Google Analytics is a pre-requisite and must be loaded for this component.');
if (!ko) throw new Error('KnockoutJS is a pre-requisite and must be loaded for this component.');
if (!sammy) throw new Error('SammyJS is a pre-requisite and must be loaded for this component.');
// END _PREBUNDLE.FRAGMENT
///#source 1 1 /js/File1.js
var ma;
(function (ma) {
var File1 = (function() {
function File1() {
// blah
}
return File1;
})();
ma.File1 = File1;
})(ma || (ma = {}));
//# sourceMappingURL=file1.js.map
///#source 1 1 /js/_postbundle.fragment.js
// START _POSTBUNDLE.FRAGMENT >>
return ma;
});
// END _POSTBUNDLE.FRAGMENT
Это создает единый элемент require, а также поддерживает использование без RequireJS, что приятно, когда я хочу сделать его общедоступным. Кроме того, я могу объединить несколько разных вариантов кода для использования на других страницах. Не уверен, есть ли лучший способ сделать это, но это работает для меня...
module(name:string)
работает с именем файла, поэтому модуль не может быть распределен по нескольким файлам.