【问题标题】:Turn certain observableArray objects properties into observable将某些 observableArray 对象属性转换为 observable
【发布时间】:2013-07-29 07:24:12
【问题描述】:

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

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

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

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

是否可以通过一些很酷的 hack 语法将其与淘汰工具进行映射,还是我必须遍历每个对象并将其状态属性映射到可观察的或让整个数组及其对象属性可观察?

【问题讨论】:

    标签: javascript knockout.js knockout-mapping-plugin


    【解决方案1】:

    您可以使用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,其中包含状态为可观察对象且名称为常规属性的对象。

    See fiddle

    @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;
    }});
    

    See updated fiddle

    您也可以将observe 与映射参数一起使用

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

    See fiddle

    希望对你有帮助。

    【讨论】:

    • 如果对象有更多的属性,而我只希望其中一个是可观察的,我是否需要明确列出每个属性,无论是否可观察?
    • 遇到了这样的事情,但你的方式看起来更专业 :D 我再次好奇的是一件简单的事情:var vm = ko.mapping.fromJS(data, {}); 是否与 var vm; ko.mapping.fromJS(data, {}, vm); 相同
    • 第一次调用是初始调用,第二次是更新。当您从服务器收到“新鲜”数据并且需要更新现有视图模型时,更新“手段”。
    【解决方案2】:

    我建议使用copy

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

    var mappingPeople = {
        'copy': ["name"]
    };
    
    var mapping = {
        create: function (opts) {
            return ko.mapping.fromJS(opts.data, mappingPeople);
        }
    };
    var PeopleArr = ko.mapping.fromJS(people, mapping);
    

    这里是Working Demo

    更新

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

    这是我的 Example 的更新,使用 observe

    【讨论】:

    • 这仍然让我需要列出所有我不想成为可观察对象的属性,这些属性占大多数。我的目标是只列出我想观察的那些。我按照 Damien 建议的方式进行操作,虽然不是那么清晰和类似淘汰赛,但它奏效了。
    • @patryk 在这种情况下,您需要使用“观察”knockoutjs.com/documentation/…
    • 观察是我的第一个镜头,不幸的是我无法将其应用于数组。无论如何,比较 Damien 他的答案的两种方法,当涉及到对象包含许多属性的情况时,哪种方法更有效?
    【解决方案3】:

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

    假设您执行了一个获取请求,并返回了一组帖子。对于每个条目,您都有一个名为“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 方法中做同样的事情。

    【讨论】:

      猜你喜欢
      • 2023-03-06
      • 2014-07-05
      • 2014-11-12
      • 2016-03-18
      • 2017-11-05
      • 2016-05-04
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      相关资源
      最近更新 更多