|
1 | | -/*ko.viewmodel.js - version 2.0.3 |
| 1 | +/*ko.viewmodel.js - version 2.0.3 |
2 | 2 | * Copyright 2013, Dave Herren http://coderenaissance.github.com/knockout.viewmodel/ |
3 | 3 | * License: MIT (http://www.opensource.org/licenses/mit-license.php)*/ |
4 | 4 | /*jshint eqnull:true, boss:true, loopfunc:true, evil:true, laxbreak:true, undef:true, unused:true, browser:true, immed:true, devel:true, sub: true, maxerr:50 */ |
5 | 5 | /*global ko:false */ |
6 | 6 |
|
7 | 7 | (function () { |
8 | 8 | //Module declarations. For increased compression with simple settings on the closure compiler, |
9 | | - //the ko functions are stored in variables. These variable names will be shortened by the compiler, |
| 9 | + //the ko functions are stored in variables. These variable names will be shortened by the compiler, |
10 | 10 | //whereas references to ko would not be. There is also a performance savings from this. |
11 | 11 | var unwrap = ko.utils.unwrapObservable, |
12 | 12 | isObservable = ko.isObservable, |
|
70 | 70 |
|
71 | 71 | //while dates aren't part of the JSON spec it doesn't hurt to support them as it's not unreasonable to think they might be added to the model manually. |
72 | 72 | //undefined is also not part of the spec, but it's currently be supported to be more in line with ko.mapping and probably doesn't hurt. |
73 | | - function isPrimativeOrDate(obj) { |
| 73 | + function isPrimitiveOrDate(obj) { |
74 | 74 | return obj === null || obj === undefined || obj.constructor === String || obj.constructor === Number || obj.constructor === Boolean || obj instanceof Date; |
75 | 75 | } |
76 | 76 |
|
|
81 | 81 |
|
82 | 82 | if (customPathSettings = pathSettings.custom) { |
83 | 83 | optionProcessed = true; |
84 | | - //custom can either be specified as a single map function or as an |
| 84 | + //custom can either be specified as a single map function or as an |
85 | 85 | //object with map and unmap properties |
86 | 86 | if (typeof customPathSettings === "function") { |
87 | 87 | result = customPathSettings(modelObj); |
|
107 | 107 | optionProcessed = true; |
108 | 108 | return badResult; |
109 | 109 | } |
110 | | - else if (isPrimativeOrDate(modelObj)) { |
111 | | - //primative and date children of arrays aren't mapped... all others are |
| 110 | + else if (isPrimitiveOrDate(modelObj)) { |
| 111 | + //primitive and date children of arrays aren't mapped... all others are |
112 | 112 | result = context.parentIsArray ? modelObj : makeObservable(modelObj); |
113 | 113 | } |
114 | 114 | else if (modelObj instanceof Array) { |
|
161 | 161 | full: context.full + "." + p |
162 | 162 | }; |
163 | 163 | childObj = modelObj[p]; |
164 | | - childPathSettings = isPrimativeOrDate(childObj) ? getPathSettings(settings, newContext) : undefined; |
| 164 | + childPathSettings = isPrimitiveOrDate(childObj) ? getPathSettings(settings, newContext) : undefined; |
165 | 165 |
|
166 | 166 | if (childPathSettings && childPathSettings.custom) {//primativish value w/ custom maping |
167 | | - //since primative children cannot store their own custom functions, handle processing here and store them in the parent |
| 167 | + //since primitive children cannot store their own custom functions, handle processing here and store them in the parent |
168 | 168 | result.___$customChildren = result.___$customChildren || {}; |
169 | 169 | result.___$customChildren[p] = childPathSettings.custom; |
170 | 170 |
|
|
219 | 219 | else if (viewModelObj && viewModelObj.___$unmapCustom) {//Defer to customUnmapping where specified |
220 | 220 | result = viewModelObj.___$unmapCustom(viewModelObj); |
221 | 221 | } |
222 | | - else if ((wasWrapped && isPrimativeOrDate(unwrapped)) || isNullOrUndefined(unwrapped)) { |
| 222 | + else if ((wasWrapped && isPrimitiveOrDate(unwrapped)) || isNullOrUndefined(unwrapped)) { |
223 | 223 | //return null, undefined, values, and wrapped primativish values as is |
224 | 224 | result = unwrapped; |
225 | 225 | } |
|
271 | 271 | return result; |
272 | 272 | } |
273 | 273 |
|
274 | | - function recursiveUpdate(modelObj, viewModelObj, context, parentObj, noncontiguousObjectUpdateCount) { |
| 274 | + function recursiveUpdate(modelObj, viewModelObj, context, parentObj, nonContiguousObjectUpdateCount) { |
275 | 275 | var p, q, foundModels, foundViewmodels, modelId, viewmodelId, idName, length, unwrapped = unwrap(viewModelObj), |
276 | 276 | wasWrapped = (viewModelObj !== unwrapped), child, map, tempArray, childTemp, childMap, unwrappedChild, tempChild; |
277 | 277 |
|
|
280 | 280 | } |
281 | 281 |
|
282 | 282 | if (wasWrapped && (isNullOrUndefined(unwrapped) ^ isNullOrUndefined(modelObj))) { |
283 | | - //if you have an observable to update and either the new or old value is |
| 283 | + //if you have an observable to update and either the new or old value is |
284 | 284 | //null or undefined then update the observable |
285 | 285 | viewModelObj(modelObj); |
286 | 286 | } |
|
294 | 294 | else { |
295 | 295 | child = unwrapped[p]; |
296 | 296 |
|
297 | | - if (!wasWrapped && unwrapped.hasOwnProperty(p) && (isPrimativeOrDate(child) || (child && child.constructor === Array))) { |
| 297 | + if (!wasWrapped && unwrapped.hasOwnProperty(p) && (isPrimitiveOrDate(child) || (child && child.constructor === Array))) { |
298 | 298 | unwrapped[p] = modelObj[p]; |
299 | 299 | } |
300 | 300 | else if (child && typeof child.___$mapCustom === "function") { |
|
314 | 314 | unwrapped[p] = modelObj[p]; |
315 | 315 | } |
316 | 316 | else {//Recursive update everything else |
317 | | - if (!!noncontiguousObjectUpdateCount) { |
| 317 | + if (!!nonContiguousObjectUpdateCount) { |
318 | 318 | var fnRecursivePropertyObjectUpdate = (function (modelObj, viewModelObj, p) { |
319 | 319 | return function () {//keep in sync with else below |
320 | 320 | recursiveUpdate(modelObj[p], unwrapped[p], { |
321 | 321 | name: p, |
322 | 322 | parent: (context.name === "[i]" ? context.parent : context.name) + "." + p, |
323 | 323 | full: context.full + "." + p |
324 | | - }, unwrapped, noncontiguousObjectUpdateCount); |
325 | | - noncontiguousObjectUpdateCount(noncontiguousObjectUpdateCount() - 1); |
| 324 | + }, unwrapped, nonContiguousObjectUpdateCount); |
| 325 | + nonContiguousObjectUpdateCount(nonContiguousObjectUpdateCount() - 1); |
326 | 326 | }; |
327 | 327 | }(modelObj, viewModelObj, p)); |
328 | | - noncontiguousObjectUpdateCount(noncontiguousObjectUpdateCount() + 1); |
| 328 | + nonContiguousObjectUpdateCount(nonContiguousObjectUpdateCount() + 1); |
329 | 329 | setTimeout(fnRecursivePropertyObjectUpdate, 0); |
330 | 330 | } |
331 | 331 | else {//keep in sync with if above |
|
358 | 358 | child(unwrap(tempChild)); |
359 | 359 | } |
360 | 360 | //else custom mapping returned previous observable; |
361 | | - //if it's smart enough to do that, assume it updated it correctly |
| 361 | + //if it's smart enough to do that, assume it updated it correctly |
362 | 362 | } |
363 | 363 | else { |
364 | 364 | unwrapped[q] = child.___$mapCustom(modelObj[p], child); |
365 | 365 | } |
366 | 366 | } |
367 | 367 | else { |
368 | | - |
369 | | - if (!!noncontiguousObjectUpdateCount) {//keep in sync with else block below |
| 368 | + |
| 369 | + if (!!nonContiguousObjectUpdateCount) {//keep in sync with else block below |
370 | 370 | var fnRecursiveArrayChildObjectUpdate = (function (modelObj, viewModelObj, p, q) { |
371 | 371 | return function () { |
372 | 372 | recursiveUpdate(modelObj[p], unwrapped[q], { |
373 | 373 | name: "[i]", parent: context.name + "[i]", full: context.full + "[i]" |
374 | | - }, undefined, noncontiguousObjectUpdateCount); |
| 374 | + }, undefined, nonContiguousObjectUpdateCount); |
375 | 375 |
|
376 | | - noncontiguousObjectUpdateCount(noncontiguousObjectUpdateCount() - 1); |
| 376 | + nonContiguousObjectUpdateCount(nonContiguousObjectUpdateCount() - 1); |
377 | 377 | }; |
378 | 378 | }(modelObj, viewModelObj, p, q)); |
379 | | - noncontiguousObjectUpdateCount(noncontiguousObjectUpdateCount() + 1); |
| 379 | + nonContiguousObjectUpdateCount(nonContiguousObjectUpdateCount() + 1); |
380 | 380 | setTimeout(fnRecursiveArrayChildObjectUpdate, 0); |
381 | 381 | } |
382 | 382 | else {//keep in sync with if block above |
|
423 | 423 | viewModelObj(modelObj); |
424 | 424 | } |
425 | 425 |
|
426 | | - if (context.name === "{root}" && !!noncontiguousObjectUpdateCount) { |
| 426 | + if (context.name === "{root}" && !!nonContiguousObjectUpdateCount) { |
427 | 427 | return { |
428 | 428 | onComplete:function (fnOnComplete) { |
429 | 429 | if(fnOnComplete && typeof fnOnComplete == "function"){ |
430 | | - if (!!noncontiguousObjectUpdateCount) { |
| 430 | + if (!!nonContiguousObjectUpdateCount) { |
431 | 431 | ko.computed(function () { |
432 | | - if (fnOnComplete && noncontiguousObjectUpdateCount() === 0) { |
| 432 | + if (fnOnComplete && nonContiguousObjectUpdateCount() === 0) { |
433 | 433 | fnOnComplete(); |
434 | 434 | fnOnComplete = undefined; |
435 | 435 | } |
|
487 | 487 | initInternals(this.options, "Mapping To Model"); |
488 | 488 | return recursiveTo(viewmodel, rootContext); |
489 | 489 | }, |
490 | | - updateFromModel: function fnUpdateFromModel(viewmodel, model, makeNoncontiguousObjectUpdates) { |
491 | | - var noncontiguousObjectUpdateCount = makeNoncontiguousObjectUpdates ? ko.observable(0) : undefined; |
| 490 | + updateFromModel: function fnUpdateFromModel(viewmodel, model, makeNonContiguousObjectUpdates) { |
| 491 | + var nonContiguousObjectUpdateCount = makeNonContiguousObjectUpdates ? ko.observable(0) : undefined; |
492 | 492 | initInternals(this.options, "Update From Model"); |
493 | | - return recursiveUpdate(model, viewmodel, rootContext, undefined, noncontiguousObjectUpdateCount); |
| 493 | + return recursiveUpdate(model, viewmodel, rootContext, undefined, nonContiguousObjectUpdateCount); |
494 | 494 | } |
495 | 495 | }; |
496 | 496 | }()); |
0 commit comments