dataflux 1.15.1 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -1
- package/dist/BasicObj.js +3 -0
- package/dist/ReactStore.js +16 -3
- package/dist/Store.js +4 -1
- package/dist/dataflux.min.js +1 -1
- package/dist/dataflux.min.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -254,6 +254,70 @@ function MyComponent() {
|
|
|
254
254
|
}
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
+
### Example 7 - React props and observability
|
|
258
|
+
|
|
259
|
+
If you pass an object as a prop to a React component, the component will not refresh if the object changes.
|
|
260
|
+
|
|
261
|
+
```jsx
|
|
262
|
+
class MyComponent extends React.Component {
|
|
263
|
+
constructor(props) {
|
|
264
|
+
super(props);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
componentDidMount() {
|
|
268
|
+
store.findAll("book", "books", this, ({price}) => price < 20);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
render(){
|
|
272
|
+
const {books} = this.state;
|
|
273
|
+
|
|
274
|
+
return books.map(book =>
|
|
275
|
+
<BookView
|
|
276
|
+
// key={book.getFingerprint()}
|
|
277
|
+
book={book}
|
|
278
|
+
/>);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
class BookView extends React.Component {
|
|
283
|
+
constructor(props) {
|
|
284
|
+
super(props);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
render(){
|
|
288
|
+
const {book} = this.props;
|
|
289
|
+
|
|
290
|
+
return <div>book.price</div>;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
If you now do `books[0].set("price", 18)`, the BookView object will not update the price. You could address this by adding a `key={book.getFingerprint()}` prop. However, this approach forces the mounting of the component at every object change.
|
|
298
|
+
|
|
299
|
+
A better approach is to use the method `didUpdate()` inside `componentDidUpdate` to check if any of the objects in the props changed.
|
|
300
|
+
|
|
301
|
+
```jsx
|
|
302
|
+
class BookView extends React.Component {
|
|
303
|
+
constructor(props) {
|
|
304
|
+
super(props);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
componentDidUpdate() {
|
|
308
|
+
store.didUpdate(this);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
render(){
|
|
312
|
+
const {book} = this.props;
|
|
313
|
+
|
|
314
|
+
return <div>book.price</div>;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Without further changes to the code, the new `book.price` will be rendered when the book object in the props is edited.
|
|
320
|
+
|
|
257
321
|
|
|
258
322
|
## Configuration
|
|
259
323
|
|
|
@@ -576,6 +640,7 @@ The store has the following method.
|
|
|
576
640
|
| reset(type) | This method syncs all the objects in the store with the remote version offered by the REST APIs (`remote -> local`). Remote changes are applied locally, including adding/removing objects. Objects edited locally but not yet persisted are reverted to the corresponding remote object. If a model type is passed, only objects of that type will be reset. |
|
|
577
641
|
| findSync(type, filterFunction) | This method returns the objects in a synchronous way (no Promise). However, *it works only if you already performed an async operation (e.g., like refresh, load, find, subscribe) or if you set lazyLoad to false and the store had enough time to load.* |
|
|
578
642
|
| hasChanged(type, object) | This method receives in input a model type and an object (optional). It returns a boolean, `true` if the object is dirty (it changed but it has not yet being persisted). If the object is not passed, the method checks if any of the objects of the specified model type has changed. |
|
|
643
|
+
| didUpdate(context) | If you pass an object as a prop to a React component, the component will not refresh if the object changes. To address this, you can use this method inside the `componentDidUpdate` to check if any of the objects changed. See [example 6](#example-7---react-props-and-observability) |
|
|
579
644
|
|
|
580
645
|
### Insert vs. Mock
|
|
581
646
|
|
|
@@ -631,6 +696,7 @@ Each object created is enriched with the following methods.
|
|
|
631
696
|
| getError() | If an operation on an object triggers an error, this error can be retrieved with `getError()`. This allows to observe specific objects' errors, instead of the generic `store.on("error", ...)`. |
|
|
632
697
|
| getError(attributeName) | This method allows you to check if the specificed attribute generated any error according to the validation property specified in the model. See [objects validation](#objects-validation). |
|
|
633
698
|
| setError(error) | Additionally to DataFlux's errors, you can trigger your own errors with this method. Other components observing this objet's error will be notified. |
|
|
699
|
+
| isDataflux() | This method returns true for all dataflux objects. |
|
|
634
700
|
|
|
635
701
|
### Deep Objects
|
|
636
702
|
When a model is declared with the option `deep: true` (default, see [model creation](#models-creation)), all the sub objects will also offer many of the methods above.
|
|
@@ -718,7 +784,7 @@ class MyComponent extends React.Component {
|
|
|
718
784
|
return <TextField
|
|
719
785
|
value={book.title}
|
|
720
786
|
onChange={store.handleChange(book, "title")}
|
|
721
|
-
error={object.getError("title")}
|
|
787
|
+
error={object.getError("title")}
|
|
722
788
|
// E.g., in material UI the test field will be red in case of errors
|
|
723
789
|
/>;
|
|
724
790
|
}
|
package/dist/BasicObj.js
CHANGED
|
@@ -78,6 +78,9 @@ var BasicObj = exports.BasicObj = /*#__PURE__*/function () {
|
|
|
78
78
|
_classPrivateFieldInitSpec(this, _id, null);
|
|
79
79
|
_classPrivateFieldInitSpec(this, _error, {});
|
|
80
80
|
_classPrivateFieldInitSpec(this, _model, void 0);
|
|
81
|
+
_defineProperty(this, "isDataflux", function () {
|
|
82
|
+
return true;
|
|
83
|
+
});
|
|
81
84
|
_defineProperty(this, "setId", function (id) {
|
|
82
85
|
_this.id = id;
|
|
83
86
|
});
|
package/dist/ReactStore.js
CHANGED
|
@@ -22,12 +22,12 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
22
22
|
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
|
|
23
23
|
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
|
|
24
24
|
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
|
|
25
|
-
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
26
|
-
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
27
|
-
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
28
25
|
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
|
|
29
26
|
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
|
|
30
27
|
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
28
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
29
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
30
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
31
31
|
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
|
|
32
32
|
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } /*
|
|
33
33
|
* MIT License
|
|
@@ -60,6 +60,19 @@ var ReactStore = exports["default"] = /*#__PURE__*/function (_ObserverStore) {
|
|
|
60
60
|
_classCallCheck(this, ReactStore);
|
|
61
61
|
_this = _callSuper(this, ReactStore, [options]);
|
|
62
62
|
_classPrivateMethodInitSpec(_this, _ReactStore_brand);
|
|
63
|
+
_defineProperty(_this, "didUpdate", function (context) {
|
|
64
|
+
var _context$props;
|
|
65
|
+
var objects = Object.values((_context$props = context === null || context === void 0 ? void 0 : context.props) !== null && _context$props !== void 0 ? _context$props : {}).filter(function (i) {
|
|
66
|
+
return i.isDataflux();
|
|
67
|
+
});
|
|
68
|
+
var _f = objects.map(function (i) {
|
|
69
|
+
return i.getFingerprint();
|
|
70
|
+
}).join(".");
|
|
71
|
+
if (_f !== context.___obs_f) {
|
|
72
|
+
context.forceUpdate();
|
|
73
|
+
}
|
|
74
|
+
context.___obs_f = _f;
|
|
75
|
+
});
|
|
63
76
|
_classPrivateFieldInitSpec(_this, _addSubscriptionToContext, function (context, subKey) {
|
|
64
77
|
// I know...
|
|
65
78
|
context.___obs_subkeys = context.___obs_subkeys || [];
|
package/dist/Store.js
CHANGED
|
@@ -359,6 +359,9 @@ var Store = exports["default"] = /*#__PURE__*/function () {
|
|
|
359
359
|
key: "hasChanged",
|
|
360
360
|
value: function hasChanged(type, object) {
|
|
361
361
|
var _this8 = this;
|
|
362
|
+
if (!this.models[type]) {
|
|
363
|
+
throw new Error("Not valid model type");
|
|
364
|
+
}
|
|
362
365
|
var _hasChanged = function _hasChanged(type, object) {
|
|
363
366
|
var obj = _this8.models[type].storedObjects[object.getId()];
|
|
364
367
|
return !obj || obj.fingerprint !== obj.object.getFingerprint();
|
|
@@ -367,7 +370,7 @@ var Store = exports["default"] = /*#__PURE__*/function () {
|
|
|
367
370
|
return _hasChanged(type, object);
|
|
368
371
|
} else {
|
|
369
372
|
return Object.values(this.models[type].storedObjects).some(function (i) {
|
|
370
|
-
return _hasChanged(type, i);
|
|
373
|
+
return _hasChanged(type, i.object);
|
|
371
374
|
});
|
|
372
375
|
}
|
|
373
376
|
}
|