Comparing version 0.1.0 to 0.1.1
44
index.js
@@ -1,3 +0,2 @@ | ||
var Collection, Model, ko, ref, | ||
slice = [].slice; | ||
var Collection, Model, ko, ref; | ||
@@ -23,3 +22,3 @@ ko = require('knockout'); | ||
key = keys[i]; | ||
results.push("change:" + key); | ||
results.push(`change:${key}`); | ||
} | ||
@@ -101,8 +100,23 @@ return results; | ||
/* | ||
* Functional wrappers | ||
*/ | ||
ko.subscribable.fn.toObservableModel = function(...keys) { | ||
return this.extend({ | ||
modelChange: keys | ||
}); | ||
}; | ||
ko.subscribable.fn.toObservableCollection = function() { | ||
return this.extend({ | ||
collectionChange: true | ||
}); | ||
}; | ||
/* | ||
* Easy to use wrapped extensions | ||
*/ | ||
ko.observableModel = function() { | ||
var keys, model; | ||
model = arguments[0], keys = 2 <= arguments.length ? slice.call(arguments, 1) : []; | ||
ko.observableModel = function(model, ...keys) { | ||
if (arguments.length === 2 && Array.isArray(keys[0])) { | ||
@@ -126,13 +140,10 @@ keys = keys[0]; | ||
sub = obsv.subscribe(function(new_value) { | ||
var obj; | ||
if (new_value === model.get(key)) { | ||
return; | ||
} | ||
return model.set(( | ||
obj = {}, | ||
obj["" + key] = new_value, | ||
obj | ||
)); | ||
return model.set({ | ||
[`${key}`]: new_value | ||
}); | ||
}); | ||
model.on("change:" + key, handler = function(model, new_value) { | ||
model.on(`change:${key}`, handler = function(model, new_value) { | ||
return obsv(new_value); | ||
@@ -143,3 +154,3 @@ }); | ||
sub.dispose(); | ||
model.off("change:" + key, handler); | ||
model.off(`change:${key}`, handler); | ||
return og_dispose != null ? og_dispose.apply(obsv, arguments) : void 0; | ||
@@ -150,5 +161,4 @@ }; | ||
ko.observableAttributes = function() { | ||
var attrs, i, key, keys, len, model; | ||
model = arguments[0], keys = 2 <= arguments.length ? slice.call(arguments, 1) : []; | ||
ko.observableAttributes = function(model, ...keys) { | ||
var attrs, i, key, len; | ||
attrs = {}; | ||
@@ -155,0 +165,0 @@ if (arguments.length === 2 && Array.isArray(keys[0])) { |
@@ -6,3 +6,3 @@ { | ||
"license": "MIT", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"main": "index.js", | ||
@@ -9,0 +9,0 @@ "scripts": { |
@@ -13,3 +13,3 @@ Introduction | ||
becomes: How can I best map all my data from the server. There are plugins for that or you can use one of many packages to integrate with a model framework. | ||
Ultimately the problem still ends up falling on the lose concept of what a ViewModel is. In practive people tend to write 2 types of ViewModels: | ||
Ultimately the problem still ends up falling on the lose concept of what a ViewModel is. In practice people tend to write 2 types of ViewModels: | ||
@@ -26,20 +26,12 @@ * Application Logic View Models: these view models contain specific logic require to handle UI manipulation on your pages, sections, panels, controls, etc.. | ||
This was the primary solution React was trying to solve. By componentizing the Application Logic View Models to own their own state representation and essentially | ||
removing Data Model View Models from the equation by forcing directionality in store interactions it's not nearly as easy to create this tangled web. That being | ||
said React doesn't do anything particularly revolutionary as their marketting would let on. And the same patterns can be applied to Knockout. React critizes mutable | ||
data and 2 way bindnig but most Knockout bindings save (checked, and value) are only one way. If anything the 2 way binding is just a convenience to reduce unnecessary | ||
boilerplate. In fact in many ways Knockout Dependency Detection Based approach with defered Microtasks is superior to Virtual DOM. Where React is constantly | ||
recalculating everything (relatively inexpensive) and then only diffing the DOM changes, Knockout is only recalculating what has changed and then only updating the DOM | ||
where it's changed in batches. This is even more efficient. This is also unlike the much slower Dirty Checking method employed by earlier versions of Angular and Ember | ||
that React compared itself to since Dirty Check requires checking all dependencies every render cycle. Mind you React can also be expanded to have fine grained control | ||
it's just a more imperative process that involves lifecycle functions and procedural code that usually ends up resembling large select statements. Whereas Knockout is | ||
built for fine grained control. The advantage of this becomes immediately obvious if you've ever tried to integrate your own store logic or deal with nested data | ||
structures. You need to build your own mechanism on top of React Component State. Finding the right store mechanism is a bit of the search for the Holy Grail because | ||
none them quite feel right and they are always a conceptual complication added on top. | ||
removing Data Model View Models from the equation by forcing directionality in store interactions it's not nearly as easy to create this tangled web. The same | ||
patterns can be applied to Knockout. Most Knockout bindings save (checked, and value) are only one way. If anything the 2 way binding is just a convenience to reduce | ||
unnecessary boilerplate. | ||
However when it comes when it comes to just getting started React is very simple because it gives the impression when dealing with state you are dealing with plain | ||
JS objects. Mapping happens as part of the render procedure instead of being yet another part of the state being stored in the View Model. Given Knockout is already | ||
very efficient only redrawing changes in the DOM it's ok to loosen how many things get recalculated in certain cases to promote simplicity. That is the goal of this | ||
project. Instead of attempting to map all the model attributes in every situation we just set tell Knockout to recalculate values when certain fields on the model or | ||
collections change. It's less efficient but not by much since it will only render the DOM if the value changed and the update cycles are still localized. Since most | ||
binding is one way it lets you deal with the models and collections directly in the view in many cases instead of mapped observables. | ||
Knockout is built for fine grained control. The advantage of this becomes immediately obvious if you've ever tried to integrate your own store logic or deal with | ||
nested data structures. Given Knockout is already very efficient only redrawing changes in the DOM it's ok to loosen how many things get recalculated in certain | ||
cases to promote React-like simplicity. That is the goal of this project. Instead of attempting to map all the model attributes in every situation we just set tell | ||
Knockout to recalculate values when certain fields on the model or collections change. It's less efficient but not by much since it will only render the DOM if the | ||
value changed and the update cycles are still localized. Since most binding is one way it lets you deal with the models and collections directly in the view in many | ||
cases instead of mapped observables. | ||
@@ -49,8 +41,8 @@ Documentation | ||
Backout provides too Knockout Extenders that are wrapped in simple to use specialized Observables. | ||
Backout provides two Knockout Extenders that are wrapped in simple to use specialized Observables. | ||
* ko.observableModel(model, ...keys) - creates an observable that notifies subscribers on setting the model, and/or on key change events | ||
* ko.observableCollection(collection) - creates an observable that notifies subscribers on setting the collection and/or on add, remove, reset, and sort | ||
* ko.observableAttribute(model, key) - creates an ko.observable that is bound to the model attribute | ||
* ko.observableAttributes(model, keys) - returns an object with an observableAttribute for each key | ||
* ko.observableAttribute(model, key) - creates an ko.observable that is bound to the model attribute. Useful for 2 way binding. | ||
* ko.observableAttributes(model, ...keys) - returns an object with an observableAttribute for each key | ||
@@ -80,5 +72,3 @@ So to set up a View Model with Backout one would use methods like the following: | ||
this.mapUser = function (model) { return ko.observableModel(model); } // write a function to map nested View Models if necessary to use. | ||
From here you could bind to the DOM like: | ||
@@ -92,3 +82,3 @@ | ||
<ul data-bind="foreach: list().models"> | ||
<li data-bind="with: mapUser($data)"> | ||
<li data-bind="with: ko.observableModel($data)"> | ||
<span data-bind="text: get('first_name')"></span> | ||
@@ -95,0 +85,0 @@ </li> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
150
11213
87