使用ko.mapping创建一个带有observables的UN观察数组?

时间:2013-10-31 20:58:30

标签: knockout.js knockout-mapping-plugin

我正在使用ko.mapping实用程序设置我的模型。

传入我的主数据时,请将我的某个属性视为数组。这个数组是每周7天的一个对象,所以我知道这个数组不会改变也不会重新排列。我可以轻松地将此数组生成为具有平面属性的JSON对象的副本,或者作为具有观察或平面属性的observableArray生成,但是我通过映射实用程序似乎无法创建一个平面数组,其中包含基本属性和观察到的属性。

我已经尝试了各种映射选项的排列,但它仍然看起来好像我将不得不映射这个数组,或者只是咬我的不间断和肛门的冲动,让这个复杂的模型准确映射我想要的方式我想映射它。

更好地展示问题:

var PrimaryViewModelMapping = {
    copy: ['KeyProperty', 'ArrayOfDays'],
    create: function(options) { return new PrimaryViewModel(options.data); }
}

这将在我的PrimaryViewModel实例中给我一个数组的平面副本,而不需要任何额外的努力......但是如果没有在我的PrimaryViewModel声明中循环遍历数组并执行操作,则无法控制ArrayOfDays中的属性。 / p>

继续:

var PrimaryViewModelMapping = {
    copy: ['KeyProperty'],
    observe: ['ArrayOfDays'],
    create: function(options) { return new PrimaryViewModel(options.data); }
}

这样可以很好地将我的ArrayOfDays打包为一个可观察的数组,同时保持其所有“每个”属性变平。

接下来的尝试如下:

var PrimaryViewModelMapping = {
    copy: ['KeyProperty'],
    'ArrayOfDays': {
        copy: ['Date'],
        observe: ['TotalDuration'],
        create: function(options) {
            return new DayArrayModel(options.data);
        }
    }
}

这使得一个可观察的数组让我完全控制观察到的内容(TotalDuration)和未观察到的内容(KeyProperty)以及我的对象DayArrayModel的声明,以及我可能想要做的任何其他事情......

但是ArrayOfDays仍然是一个可观察的数组。我不需要也不想要它。

理解这里的主题是特定于映射插件的,我不想在PrimaryViewModel声明中创建循环来处理这个......我知道我可以做。只是想知道我是否偶然发现了一个“功能请求”,或者我是不是没有得到它。

感谢。

2 个答案:

答案 0 :(得分:2)

如果您坚持想要阻止ArrayOfDays成为常规数组,则可以使用ko.utils.arrayMap方法。但是,你想要的东西与映射插件的作用完全不同,所以它会变得有点冗长。

问题是映射选项不允许您指定单个属性的构造方式,您只能告诉插件包含或排除属性,或者如何在数组中生成元素。因此,您的第一步是直接生成主视图模型 。相反,你可以这样做:

var MainViewModel = function(data) {
    var self = this;

    var mappingOptions = {
        'exclude': ['ArrayOfDays']
    };

    // Map everything, except the array
    ko.mapping.fromJS(data, mappingOptions, self);

    // Do the array itself, but prevent it from becoming an *observable* array
    self.ArrayOfDays = ko.utils.arrayMap(data.ArrayOfDays, function(item) { return new DayViewModel(item); });
};

这做了一些事情:

  1. 创建self以防止任何讨厌的this问题;
  2. 设置一个选项变量,告诉KO我们将自己处理数组。
  3. self。{/ li>之上映射除数组之外的所有
  4. 自己处理阵列。
  5. 这里的关键是ko.utils.arrayMap将返回一个平面数组,而不是observableArray。

    这是a fiddle to demonstrate this

    作为一个脚注,我不清楚为什么你想要这样的东西(或许过早优化?)。

答案 1 :(得分:0)

我来到了一个墙上,主题是在Knockout中进行映射。我确实爬过这堵墙,但我仍然感到困惑。从高级用例的角度来看,映射插件似乎只是模糊数据与Knockout绑定的viewModel之间的连接。

我从 http://www.coderenaissance.com/ 中发现了以下列表(并添加了评论),这似乎还有一个似乎没有获得的映射插件的另一种变体很受关注。我喜欢创作者的洞察力,因为它与我自己的经验相吻合......

  • 在大型视图模型上运行缓慢,特别是在较旧的模型中 浏览器(IE7 / 8)和大型数组。 (不是那么大的交易......)
  • 在调用之后创建视图模型不是一步到位的过程 映射你必须进一步扩展viewmodel。 (偶尔,对于小型存储模型,我不需要这样做, 但是对于其他属性/功能,我还有额外的功能 需要继续遵循我们现有的模式。)
  • 它没有提供组织视图模型创建代码的简单方法 在较大的视图模型上成为一个问题。 (我最大的一个 烦恼...我真的希望使用映射选项的组合 我真的可以减少重复的属性)
  • 它不允许在视图模型的创建方式上进行太多自定义 什么样的定制令人困惑,而且不直观 使用。 (视图模型的操作绝对是 不可避免的。映射程序的时间/顺序并不总是如此 可以预测的,就像我希望的那样。当你真的感到困惑 开始级联映射。)

所以,我现在第一个问题......或者笑话的妙语......就是说,没有勺子。根据我的发现,我删除了使用ko.mapping作为我的模式初始化的尝试,并且只使用它来从我的ko.applybindings命令之前的视图中准备我的初始触发器。此时,我使用了arrayMap和observable(array)的组合来填充我的对象......就像我以前一样。目前,我已经知道 何时使用映射插件。