Kaynağa Gözat

Allow arrays in key descriptor.

Herbert Vojčík 7 yıl önce
ebeveyn
işleme
b0cefcedaa
2 değiştirilmiş dosya ile 42 ekleme ve 26 silme
  1. 32 22
      README.md
  2. 10 4
      src/cow-value-model.js

+ 32 - 22
README.md

@@ -1,12 +1,12 @@
 # redux-sac
 # redux-sac
 
 
-## Slice and compose redux-type reducers.
+## Slice redux objects (reducers, middleware, ...)
 
 
 ### `subReducer(key, reducer, additionalKey, ...)`
 ### `subReducer(key, reducer, additionalKey, ...)`
 
 
 Creates a wrapper reducer that calls `reducer`
 Creates a wrapper reducer that calls `reducer`
 on the sub-state specified by `key`.
 on the sub-state specified by `key`.
-You may use dot notation.
+Key can go in different formats, see `cowValueModel` below.
 Rest of the state is left untouched.
 Rest of the state is left untouched.
 
 
 ```js
 ```js
@@ -27,7 +27,7 @@ if `personReducer` would return the identical array,
 If persons were deeper in hierarchy, it could have been created as
 If persons were deeper in hierarchy, it could have been created as
 `const r = subReducer("files.persons", personReducer);` for example.
 `const r = subReducer("files.persons", personReducer);` for example.
 
 
-You may pass additional keys (also with possible dot-notation)
+You may pass additional keys
 as addition arguments. In that case, additional parts of state
 as addition arguments. In that case, additional parts of state
 will be fetched and passed to a sub-reducer:
 will be fetched and passed to a sub-reducer:
 
 
@@ -43,30 +43,13 @@ r({persons: ["John", "Jill"], assets: {cars: ["Honda"]}}, action);
 
 
 This technique is mentioned in Redux docs, in "Beyond combineReducers" page.
 This technique is mentioned in Redux docs, in "Beyond combineReducers" page.
 
 
-### `composeReducers(reducer1, reducer2, ...)`
-
-Creates a wrapper reducer that calls passed reducers
-one after another, passing intermediate states.
-and returning the result of the last one.
-
-Useful to "concatenate" a few `subReducer`s. like:
-
-```js
-composeReducers(
-  subReducer("files.persons", personReducer, "assets.swag"),
-  subReducer("files.clients", clientReducer, "news"),
-  subReducer("assets", assetReducer),
-  baseReducer
-)
-```
-
 ### `subMiddleware(key | selectorFn, middleware)`
 ### `subMiddleware(key | selectorFn, middleware)`
 
 
 Creates a wrapper middleware
 Creates a wrapper middleware
 on the sub-state specified by `key`
 on the sub-state specified by `key`
 or the selector function `selectorFn`
 or the selector function `selectorFn`
 by decorating `getState` part of the passed arg.
 by decorating `getState` part of the passed arg.
-You may use dot notation.
+The `key` can have different format, see `cowValueModel` below.
 Rest of the passed arg is left untouched.
 Rest of the passed arg is left untouched.
 
 
 ```js
 ```js
@@ -125,6 +108,25 @@ store.dispatch({type: "foo"});
 // console => ["John","Jill"] 
 // console => ["John","Jill"] 
 ```
 ```
 
 
+## Compose
+
+### `composeReducers(reducer1, reducer2, ...)`
+
+Creates a wrapper reducer that calls passed reducers
+one after another, passing intermediate states.
+and returning the result of the last one.
+
+Useful to "concatenate" a few `subReducer`s. like:
+
+```js
+composeReducers(
+  subReducer("files.persons", personReducer, "assets.swag"),
+  subReducer("files.clients", clientReducer, "news"),
+  subReducer("assets", assetReducer),
+  baseReducer
+)
+```
+
 ## Redux helpers
 ## Redux helpers
 
 
 ### `cowValueModel(key, ...)`
 ### `cowValueModel(key, ...)`
@@ -133,7 +135,10 @@ Creates an overloaded function allowing
 to set or get specified key from any object.
 to set or get specified key from any object.
 Get when one arg, set when two args.
 Get when one arg, set when two args.
 Specify keys by passing a list of keys to `cowValueModel`.
 Specify keys by passing a list of keys to `cowValueModel`.
-You can use dot notation.
+Key can be either:
+ - number
+ - array of Keys
+ - anything else, which is `toString()`ed and dot-split.
 
 
 Set-usage (two-arg) returns a copy with specified (sub-)property changed;
 Set-usage (two-arg) returns a copy with specified (sub-)property changed;
 in case no change actually happens, returns the original object.
 in case no change actually happens, returns the original object.
@@ -148,6 +153,11 @@ name({name: "Tom"}, "Jerry");
   
   
 const city = cowValueModel("address.city");
 const city = cowValueModel("address.city");
 const city2 = cowValueModel("address", "city");
 const city2 = cowValueModel("address", "city");
+// and other forms, like:
+// const city3 = cowValueModel(["address", "city"]);
+// const city4 = cowValueModel("address", [[], "city"]);
+// const city5 = cowValueModel([[], "address.city"]);
+// etc.
 const object = {address: {city: "New York"}};
 const object = {address: {city: "New York"}};
   
   
 city(object);
 city(object);

+ 10 - 4
src/cow-value-model.js

@@ -6,10 +6,16 @@ function copyWith (obj, key, value) {
 
 
 export const cowValueModel = (...keyDescriptions) => {
 export const cowValueModel = (...keyDescriptions) => {
     const keys = [];
     const keys = [];
-    keyDescriptions.forEach(each => {
-        if (typeof each === 'number') keys.push(each);
-        else keys.push(...each.toString().split('.'));
-    });
+
+    function fillKeys (keyDescriptions) {
+        keyDescriptions.forEach(each => {
+            if (typeof each === 'number') keys.push(each);
+            else if (Array.isArray(each)) fillKeys(each);
+            else keys.push(...each.toString().split('.'));
+        });
+    }
+
+    fillKeys(keyDescriptions);
 
 
     function setField (x = {}, index, val) {
     function setField (x = {}, index, val) {
         if (index >= keys.length) return val;
         if (index >= keys.length) return val;