我的任务是使用Typescript创建基于Knockout组件的UI。
这是我在vanilla JS中做过数百次的事情,但我似乎无法让TS以正确的格式生成JS模块以供Require JS使用。
理想情况下,我想要的是使用Typescript生成与JS编写的输出完全相同的输出,但是现在我只是想让事情有效。
这是我试图让TS生成的Javascript,这是来自不使用TS的不同项目的Javascript,并且在该项目中,当JS采用这种格式时,一切正常。
define(["knockout", "text!./menubar.html"], function (ko, menubarTemplate)
{
function menubarViewModel()
{
var self = this;
self.menuBrand = ko.observable("Menu Brand");
self.menuItems = ko.observableArray([]);
self.load();
return self;
}
menubarViewModel.prototype.load = function ()
{
var self = this;
$.getJSON("data/menudata.json", function (data)
{
self.menuItems(data);
});
};
return { viewModel: menubarViewModel, template: menubarTemplate };
});
在我使用该组件的实际JS文件中,我需要做的是:
define(["jquery", "knockout", "bootstrap"], function ($, ko)
{
ko.components.register("menubar",
{
require: "application/components/menubar"
});
ko.applyBindings();
});
菜单栏组件的HTML只是一小块简单的HTML标记,其中包含“数据绑定”属性,需要将数据注入组件。
正如我所说,这个JavaScript版本运行完美,但我目前正在工作的客户端想要在Typescript中使用它,所以我需要解决的第一个挑战是如何返回
return { viewModel: menubarViewModel, template: menubarTemplate };
来自打字稿模块。
到目前为止我取得了一些成功,例如,如果我这样做:
import ko = require("knockout");
module HelloComponent {
export class HelloViewModel {
helloText = ko.observable<string>("Hello World");
}
}
生成一个JS类,ko尝试加载,但抱怨它没有模板。
这告诉我,如果我可以使用上面的TS类并从同一个类中导出require文本HTML,那么我可能只是让它工作。
如果我按如下方式进一步扩展该课程:
import ko = require("knockout");
import helloTemplate = require("text!application/components/hello.html");
module HelloComponent {
export class HelloViewModel {
helloText = ko.observable<string>("Hello World");
}
var tmp = helloTemplate;
}
我已经尝试解决这个问题几天了,我尝试过的大部分实验都失败了,或者似乎在chrome调试器中运行,但在组件中没有输出。
这里有几十篇关于SO的帖子,但是没有一个适用于Knockout组件,所有其他帖子都适用于页面级标准绑定,这与KO组件不同,它与我发表的各种博客帖子的情况相同一直在读。
如果有人根据KnockoutJS文档中的建议了解如何实现这一点,但使用TS而不是JS,那么我很想听听你的想法。
更改我的一个组件以匹配'James Brantly的回答后,我现在在Visual Studio中看到以下内容:
即使出现上面显示的错误,我现在已经将几个组件放在一起,所有组件都采用相同的方法,一切都运行良好。
Visual Studio仍将这些文件标记为有错误,但它仍然允许我编译项目,而Typescript仍然可以执行它所需要的并编译为JavaScript。
此时,我正在回答问题,因为最初的问题已经解决了。
答案 0 :(得分:1)
我认为您的问题的关键是您希望模块返回{ viewModel: menubarViewModel, template: menubarTemplate };
之类的内容。你这样做:
import menubarTemplate = require('text!./menubar.html');
class MenubarViewModel{
}
export = {
viewModel: MenubarViewModel,
template: menubarTemplate
}
答案 1 :(得分:0)
在代码中:
import ko = require("knockout");
module HelloComponent {
您正在混合internal modules
(模块关键字现在称为命名空间)和基于文件的模块(import
关键字)。
<强>不强>
仅使用外部模块:
import ko = require("knockout");
export class HelloViewModel {
helloText = ko.observable<string>("Hello World");
}