SteveSanderson / knockout.mapping

Object mapping plugin for KnockoutJS
Other
545 stars 768 forks source link

Questions about Knockout Mapping #208

Open lzl124631x opened 8 years ago

lzl124631x commented 8 years ago

https://github.com/knockout/knockout/issues/1895

lzl124631x commented 8 years ago
var data = { a: { b: 1} };
var vm = ko.mapping.fromJS(data);
console.log(vm.a.b());

Why vm.a is not an observable? http://knockoutjs.com/documentation/plugins-mapping.html#how-things-are-mapped

lzl124631x commented 8 years ago

https://jsfiddle.net/Richard_Liu/pauzy5wL/

Why error occurs in the 3rd case?

lzl124631x commented 8 years ago

Copying certain properties using “copy”

When converting your view model back to a JS object, by default the mapping plugin will create observables based on the rules explained above.

The bold part is wrong! Shouldn't it be 'When converting your JS object to view model'?

lzl124631x commented 8 years ago

The array copy can be used for efficiency to copy array or object properties including children. If an >array or object property is not specified in copy or observe then it is recursively mapped:

var data = {
   a: "a",
   b: [{ b1: "v1" }, { b2: "v2" }] 
};

var result = ko.mapping.fromJS(data, { observe: "a" });
var result2 = ko.mapping.fromJS(data, { observe: "a", copy: "b" }); //will be faster to map.

Why doesn't knockout work in this way: if observe is specified and doesn't include the array b, b is always copied directly?

lzl124631x commented 8 years ago
console.clear();
var data = [
    { a: "a1", b: "b1" },
    { a: "a2", b: "b2" }
];

var m1 = ko.mapping.fromJS(data, { 'observe' : '[0].a' }); // can only maps the property `a` in the first element
console.log(m1());

How to only observe property a of elements in array? Is there some regex-like pattern?


I've to use the following mapping?

var mapping = {
    create: function(options) {
        return ko.mapping.fromJS(options.data, { 'observe': 'a' });
    }
}
var m2 = ko.mapping.fromJS(data, mapping);
lzl124631x commented 8 years ago

http://jsfiddle.net/Richard_Liu/vfptk976/

ko.mapping.fromJS(data, { observe: 'b' }, data); doesn't work as expected, is this a bug or designed intentionally?

lzl124631x commented 8 years ago

https://jsfiddle.net/Richard_Liu/goycbmt9/

var data = [
        { id : 1, name : 'Alice' },
        { id : 2, name : 'Bob' }
    ];
var mapping = {
    'create': function(options) {
        return options.data;
    }
}
var m1 = ko.observableArray();
ko.mapping.fromJS(data, mapping, m1);
console.log(m1.push) // m1 is an observableArray!
var m2 = ko.observable();
ko.mapping.fromJS(data, mapping, m2);
console.log(m2.push); // m2 is an observable!

So the initial type (observable or observableArray) of view model matters?

I know the right way is to use m = ko.mapping.fromJS(...) for the first time and then ko.mapping.fromJS(..., m) later on. I just think it's tiresome and hope always calling ko.mapping.fromJS(..., m) will do the work, no need to do special work at the first time.

lzl124631x commented 8 years ago

Hi there?

KantJoe commented 7 years ago

@lzl124631x using options by the way m1 should get observe.

lzl124631x commented 7 years ago

Do you mean that, in my latest question, m1 which is initialized as an observableArray, will still be an observable after ko.mapping.fromJS?