【问题标题】:Using ScriptSharp with Knockout.Mapping through RequireJS通过 RequireJS 将 ScriptSharp 与 Knockout.Mapping 一起使用
【发布时间】:2013-07-08 15:25:53
【问题描述】:

我正在为所有 Script# 依赖加载而苦苦挣扎。

我有一个引用淘汰库的脚本# 项目。一段时间后我开始使用 RequireJS。

现在我想使用符合类似规则的 KnockoutJS 映射

var model = ko.mapping.fromJS(data, {}, new ViewModel());

但是 ko.mapping 是未定义的。

如果我手动(仅用于测试)更改已编译的 .js 文件以包含如下映射:

define('MyApp',
    ['ss', 'jquery', 'knockout', knockout.mapping],
    function (ss, $, ko, mapping) { /*...*/ }
);

'mapping' 被定义,但不是'ko.mapping',这是编译器引用它的方式。

有什么想法吗?

这是我的配置:

requirejs.config({
    paths: {
        'jquery': 'jquery-1.9.1',
        'jqueryValidation': 'jquery.validate',
        'knockout': 'knockout-2.2.0',
        'knockout.mapping': 'knockout.mapping-latest.debug',
        'modernizr': 'modernizr-2.6.2'
    },
    shim: {
        'jqueryValidation': ['jquery'],
        'jquery.validate.unobtrusive': ['jquery', 'jqueryValidation'],
        'jquery.unobtrusive-ajax': ['jquery'],
        'knockout.mapping': ['knockout']
    }
});

【问题讨论】:

  • 请同时发布您的 require.config 部分

标签: requirejs knockout-mapping-plugin script#


【解决方案1】:

听起来 Script# 假设 koko.mapping 在全局命名空间中,而不是作为 AMD 加载。但是,Knockout 和 Knockout.mapping 被编码为当它们检测到 AMD/RequireJS 时,它们不使用全局命名空间。

解决此问题的几个选项:

1 - 在 require.config 被调用后立即注入(基于下面的 cmets),而不是等待某些东西实际请求敲除或敲除.mapping

requirejs.config({
    // same as original
});

require(["knockout", "knockout.mapping"], function (ko, m) {       
    ko.mapping = m; 
})

2 - 创建您自己的包装器模块,将其注入全局。像这样的:

define('knockout.inject', ['knockout'], function(k)
{
  window.ko = k; // make a ko global
  return k; // but also return what a normal AMD require expects
});

define('knockout.mapping.inject', ['knockout.mapping'], function(m)
{
  window.ko.mapping = m; // make a ko.mapping global
  return m; // but also return what a normal AMD require expects
});

然后,您可以进行 RequireJS 映射配置,以便每当您请求 'knockout' 或 'knockout.mapping' 时,它们都会透明地重新映射到您的上述包装器。

requirejs.config({
    paths: { // same as original },
    shim: { // same as original },
    map: {
      '*': {
        'knockout': 'knockout.inject',
        'knockout.mapping': 'knockout.mapping.inject'
      },
      // prevent cycles
      'knockout.inject': {'knockout': 'knockout'},
      'knockout.mapping.inject': {'knockout.mapping': 'knockout.mapping'}
    }
});

【讨论】:

  • 谢谢。看起来很有希望......但 [window.ko.mapping = m;] 永远不会被调用。并且不会抛出任何异常。有什么想法吗?
  • @Sam7 看起来我在 map 部分的语法有误。请尝试上面的编辑版本。
  • 谢谢。我已经试过了,但不是这样。我发现只需添加这行代码就可以解决问题 require(["knockout", "knockout.mapping"], function (ko, m) { ko.mapping = m; });因此,如果您想调整您的答案,我很乐意将其作为解决方案。 ;)
  • @Sam7 你在哪个文件中添加了这个?是否需要任何 map 内容?
  • 不,不需要地图的东西,也不需要“定义”的东西。相反,我将它附加到 Require 配置文件中,就在最后。在我的开发环境中一切正常。不确定我以后是否会遇到“竞争条件问题”。
【解决方案2】:

此示例 (https://github.com/nikhilk/scriptsharp/tree/cc/samples/KOWorld) 显示使用 script# + 敲除以及 requirejs 作为 AMD 加载程序。

请务必查看 AssemblyInfo.js 中的脚本模板以完成所有这些工作。

希望这会有所帮助和工作。

【讨论】:

  • 请考虑在此处发布配置的关键部分,以防链接示例演变成其他内容。基本上,您建议直接引用 Knockout 的脚本标记,而不是通过 RequireJS 加载它?
  • 谢谢尼克。我已经详细研究了 KOWorld 示例,否则我永远不会到达这里;)但是在您的示例中,没有使用映射。即使 .net 包装器显示映射类/方法,它也不包含对 knockout.mapping 库的“要求”。
猜你喜欢
  • 2012-05-31
  • 2023-03-18
  • 2014-10-06
  • 2023-04-09
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多