【问题标题】:How can I export 2 items from a Typescript Module如何从 Typescript 模块中导出 2 个项目
【发布时间】:2015-11-03 01:20:35
【问题描述】:

场景

我的任务是使用 Typescript 创建一个基于 Knockout Components 的 UI。

这是我在 vanilla JS 中做过数百次的事情,但我似乎无法让 TS 生成正确格式的 JS 模块以供 Require JS 使用。

理想情况下,我希望 Typescript 生成与用 JS 编写的输出相同的输出,但现在我只想让事情正常运行。

Javascript

这是我试图让 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 类并从同一个类中导出所需的文本 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 来实现这一点有见解,那么我很想听听你的想法。

2015 年 8 月 12 日更新(基于 James 的回复)

在更改我的一个组件以匹配“James Brantly”的答案后,我现在在 Visual Studio 中看到以下内容:

2015 年 8 月 13 日更新(测试后詹姆斯回复)

即使有上面​​显示的错误,我现在还是将几个组件放在一起,全部使用相同的方法,并且一切正常。

Visual Studio 仍然将这些文件标记为有错误,但它仍然允许我编译项目,并且 Typescript 仍然执行它需要的工作并编译为 JavaScript。

此时,我将问题标记为已回答,因为最初的问题已解决。

【问题讨论】:

  • @artem - 这不是重复的。我已经多次阅读该帖子,那是关于需要加载错误的文件。我可以成功加载模板,问题是如何让 typescript 生成我知道在其他项目中有效的 JS 输出。

标签: javascript html knockout.js typescript web-component


【解决方案1】:

在代码中:

import ko = require("knockout");

module HelloComponent {

您正在混合使用internal modules(现在称为命名空间的模块关键字)和基于文件的模块import 关键字)。

不要

仅使用外部模块:

import ko = require("knockout");

export class HelloViewModel {
  helloText = ko.observable<string>("Hello World");
}

更多:https://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1

【讨论】:

  • 这样做可以让我返回一个复合对象和/或创建与已经工作的相同或相似的 JS?
  • 好的,所以我将我的视图模型更改为那个,但我仍然看不到如何同时导出组件模板。采用您建议的更改只会让我得到一个被进一步展开的JS,并给我一个exports.blah = blah,我需要同时将VM导出为“viewModel”并将模板字符串导出为“template”,在相同的范围,以便其他模块可以获取它们。
【解决方案2】:

我认为您问题的关键是您希望模块返回类似{ viewModel: menubarViewModel, template: menubarTemplate }; 的内容。你这样做:

import menubarTemplate = require('text!./menubar.html');

class MenubarViewModel{

}

export = {
    viewModel: MenubarViewModel,
    template: menubarTemplate 
}

【讨论】:

  • 嗨,詹姆斯,谢谢,我会尝试并让您知道
  • 我已经尝试了您的建议 James,请参阅上面的更新,不幸的是,这不起作用。 :-(虽然这让我思考....
  • 好的..这很奇怪...刚刚尝试了第二次,仍然看到上面的错误,如我的更新中所见,但这次 TS 编译了我的 TS 文件并实际生成了正确的 JS使组件工作的代码!!!
  • 根据您的屏幕截图,我认为问题可能是等号后的换行符。使用export = {\n 而不是export = \n{
  • 谢谢你会尝试的 :-) 即使有错误,一切仍然编译..并且工作,所以我要标记为已回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 2022-12-15
  • 2017-04-03
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 2017-02-07
相关资源
最近更新 更多