5

假设我有这个相同类型的对象数组:

var people = [
    { status: 0, name: "name1"},
    { status: 1, name: "name2"}
];

我希望它不仅是 observableArray,而且我只想观察每个对象的状态属性。

想象一下对象本身可能会被添加或删除。这些对象中的任何一个的 name 属性都不会改变,所以我真的不需要观察名称,但是每个对象的状态都可能会改变,因此让它可观察会很酷。

是否可以使用带有一些很酷的 hack 语法的敲除实用程序来映射它,或者我是否必须遍历每个对象并将其状态属性映射到可观察的或让整个数组及其对象属性可观察?

4

3 回答 3

5

您可以使用ko.mapping.fromJS

var vm = ko.mapping.fromJS(people,{
    create: function(options){    
        return {
            status : ko.observable(options.data.status), // observable
            name: options.data.name, // non observable
        }
    }
});

现在 vm 是一个 observableArray ,其中包含对象,其中状态是可观察的,名称是常规属性。

见小提琴

@Patryk:

如果您有许多属性并且只想将一个转换为可观察的,则可以这样做。

var o = ko.mapping.fromJS(people,{create: function(options){
    // clone item
    var item = ko.utils.extend(options.data, {});
    // replace status property by an observable 
    item.status = ko.observable(options.data.status);
    return item;
}});

查看更新的小提琴

您还可以使用带有映射参数的观察

var mapping = {
    create: function (options) {
        return ko.mapping.fromJS(options.data, {'observe': ["status"]});
    }
};
var o = ko.mapping.fromJS(people, mapping);

见小提琴

我希望它有所帮助。

于 2013-07-29T13:29:39.817 回答
1

我建议使用副本

所以你可以提供你不想成为可观察的属性的数组。

var mappingPeople = {
    'copy': ["name"]
};

var mapping = {
    create: function (opts) {
        return ko.mapping.fromJS(opts.data, mappingPeople);
    }
};
var PeopleArr = ko.mapping.fromJS(people, mapping);

这是工作演示

更新

如果您需要将一个属性标记为可观察的,其余的将是普通属性,那么我建议使用观察

这是我的示例的更新,使用observe

于 2013-07-29T13:49:31.987 回答
0

我知道这个问题很老,但我遇到了同样的问题,并找到了一个简单的解决方案,而不使用任何插件。

假设您执行了一个获取请求,并返回了一组帖子。对于每个条目,您都有一个名为“Favorited”的属性,它是一个布尔值,指示该帖子是否被用户收藏,并且您希望使该属性可观察,以便您可以在某些更改其状态的函数中工作。

您可以执行以下操作:

function ViewModel() {
  var self = this;
  self.posts = ko.observableArray([]);

  $.getJSON("/api/getPosts", function(data) {
   ko.utils.arrayForEach(data, function(post) {
    post.Favorited = ko.observable(post.Favorited)
   });
   self.posts(data)
  });
}

通过这种方式,您可以将收藏的属性转换为带有其值的可观察对象,并且您可以将任何可观察的属性转换为在 arrayForEach 方法中做同样的事情。

于 2014-10-06T22:43:01.813 回答