@gogocat/data-bind 1.12.0 → 2.0.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/.editorconfig +14 -14
- package/.vscode/launch.json +12 -12
- package/CONFIGURATION.md +294 -0
- package/REACTIVE_MODE.md +553 -0
- package/README.md +266 -829
- package/babel.config.json +30 -0
- package/dist/js/_escape.d.ts +14 -0
- package/dist/js/_escape.d.ts.map +1 -0
- package/dist/js/applyBinding.d.ts +11 -0
- package/dist/js/applyBinding.d.ts.map +1 -0
- package/dist/js/attrBinding.d.ts +12 -0
- package/dist/js/attrBinding.d.ts.map +1 -0
- package/dist/js/binder.d.ts +67 -0
- package/dist/js/binder.d.ts.map +1 -0
- package/dist/js/changeBinding.d.ts +19 -0
- package/dist/js/changeBinding.d.ts.map +1 -0
- package/dist/js/commentWrapper.d.ts +39 -0
- package/dist/js/commentWrapper.d.ts.map +1 -0
- package/dist/js/config.d.ts +55 -0
- package/dist/js/config.d.ts.map +1 -0
- package/dist/js/createBindingOption.d.ts +32 -0
- package/dist/js/createBindingOption.d.ts.map +1 -0
- package/dist/js/createEventBinding.d.ts +10 -0
- package/dist/js/createEventBinding.d.ts.map +1 -0
- package/dist/js/cssBinding.d.ts +15 -0
- package/dist/js/cssBinding.d.ts.map +1 -0
- package/dist/js/dataBind.js +2756 -2530
- package/dist/js/dataBind.min.js +8 -1
- package/dist/js/dataBind.min.js.map +1 -1
- package/dist/js/domWalker.d.ts +9 -0
- package/dist/js/domWalker.d.ts.map +1 -0
- package/dist/js/forOfBinding.d.ts +12 -0
- package/dist/js/forOfBinding.d.ts.map +1 -0
- package/dist/js/hoverBinding.d.ts +13 -0
- package/dist/js/hoverBinding.d.ts.map +1 -0
- package/dist/js/ifBinding.d.ts +12 -0
- package/dist/js/ifBinding.d.ts.map +1 -0
- package/dist/js/index.d.ts +10 -0
- package/dist/js/index.d.ts.map +1 -0
- package/dist/js/modelBinding.d.ts +12 -0
- package/dist/js/modelBinding.d.ts.map +1 -0
- package/dist/js/postProcess.d.ts +3 -0
- package/dist/js/postProcess.d.ts.map +1 -0
- package/dist/js/pubSub.d.ts +11 -0
- package/dist/js/pubSub.d.ts.map +1 -0
- package/dist/js/reactiveProxy.d.ts +28 -0
- package/dist/js/reactiveProxy.d.ts.map +1 -0
- package/dist/js/renderForOfBinding.d.ts +8 -0
- package/dist/js/renderForOfBinding.d.ts.map +1 -0
- package/dist/js/renderIfBinding.d.ts +22 -0
- package/dist/js/renderIfBinding.d.ts.map +1 -0
- package/dist/js/renderIteration.d.ts +16 -0
- package/dist/js/renderIteration.d.ts.map +1 -0
- package/dist/js/renderTemplate.d.ts +14 -0
- package/dist/js/renderTemplate.d.ts.map +1 -0
- package/dist/js/renderTemplatesBinding.d.ts +19 -0
- package/dist/js/renderTemplatesBinding.d.ts.map +1 -0
- package/dist/js/showBinding.d.ts +13 -0
- package/dist/js/showBinding.d.ts.map +1 -0
- package/dist/js/switchBinding.d.ts +13 -0
- package/dist/js/switchBinding.d.ts.map +1 -0
- package/dist/js/textBinding.d.ts +13 -0
- package/dist/js/textBinding.d.ts.map +1 -0
- package/dist/js/types/_escape.d.ts +14 -0
- package/dist/js/types/_escape.d.ts.map +1 -0
- package/dist/js/types/applyBinding.d.ts +11 -0
- package/dist/js/types/applyBinding.d.ts.map +1 -0
- package/dist/js/types/attrBinding.d.ts +12 -0
- package/dist/js/types/attrBinding.d.ts.map +1 -0
- package/dist/js/types/binder.d.ts +67 -0
- package/dist/js/types/binder.d.ts.map +1 -0
- package/dist/js/types/changeBinding.d.ts +19 -0
- package/dist/js/types/changeBinding.d.ts.map +1 -0
- package/dist/js/types/commentWrapper.d.ts +39 -0
- package/dist/js/types/commentWrapper.d.ts.map +1 -0
- package/dist/js/types/config.d.ts +55 -0
- package/dist/js/types/config.d.ts.map +1 -0
- package/dist/js/types/createBindingOption.d.ts +32 -0
- package/dist/js/types/createBindingOption.d.ts.map +1 -0
- package/dist/js/types/createEventBinding.d.ts +10 -0
- package/dist/js/types/createEventBinding.d.ts.map +1 -0
- package/dist/js/types/cssBinding.d.ts +15 -0
- package/dist/js/types/cssBinding.d.ts.map +1 -0
- package/dist/js/types/domWalker.d.ts +9 -0
- package/dist/js/types/domWalker.d.ts.map +1 -0
- package/dist/js/types/forOfBinding.d.ts +12 -0
- package/dist/js/types/forOfBinding.d.ts.map +1 -0
- package/dist/js/types/hoverBinding.d.ts +13 -0
- package/dist/js/types/hoverBinding.d.ts.map +1 -0
- package/dist/js/types/ifBinding.d.ts +12 -0
- package/dist/js/types/ifBinding.d.ts.map +1 -0
- package/dist/js/types/index.d.ts +10 -0
- package/dist/js/types/index.d.ts.map +1 -0
- package/dist/js/types/modelBinding.d.ts +12 -0
- package/dist/js/types/modelBinding.d.ts.map +1 -0
- package/dist/js/types/postProcess.d.ts +3 -0
- package/dist/js/types/postProcess.d.ts.map +1 -0
- package/dist/js/types/pubSub.d.ts +11 -0
- package/dist/js/types/pubSub.d.ts.map +1 -0
- package/dist/js/types/reactiveProxy.d.ts +28 -0
- package/dist/js/types/reactiveProxy.d.ts.map +1 -0
- package/dist/js/types/renderForOfBinding.d.ts +8 -0
- package/dist/js/types/renderForOfBinding.d.ts.map +1 -0
- package/dist/js/types/renderIfBinding.d.ts +22 -0
- package/dist/js/types/renderIfBinding.d.ts.map +1 -0
- package/dist/js/types/renderIteration.d.ts +16 -0
- package/dist/js/types/renderIteration.d.ts.map +1 -0
- package/dist/js/types/renderTemplate.d.ts +14 -0
- package/dist/js/types/renderTemplate.d.ts.map +1 -0
- package/dist/js/types/renderTemplatesBinding.d.ts +19 -0
- package/dist/js/types/renderTemplatesBinding.d.ts.map +1 -0
- package/dist/js/types/showBinding.d.ts +13 -0
- package/dist/js/types/showBinding.d.ts.map +1 -0
- package/dist/js/types/switchBinding.d.ts +13 -0
- package/dist/js/types/switchBinding.d.ts.map +1 -0
- package/dist/js/types/textBinding.d.ts +13 -0
- package/dist/js/types/textBinding.d.ts.map +1 -0
- package/dist/js/types/types.d.ts +111 -0
- package/dist/js/types/types.d.ts.map +1 -0
- package/dist/js/types/util.d.ts +119 -0
- package/dist/js/types/util.d.ts.map +1 -0
- package/dist/js/types.d.ts +111 -0
- package/dist/js/types.d.ts.map +1 -0
- package/dist/js/util.d.ts +119 -0
- package/dist/js/util.d.ts.map +1 -0
- package/eslint.config.js +124 -0
- package/examples/DBMONSTER_COMPARISON.md +123 -0
- package/examples/afterRenderDemo.html +119 -0
- package/examples/bootstrap/css/animate.css +1579 -1579
- package/examples/bootstrap/css/bootstrap.min.css +6 -6
- package/examples/bootstrap/css/homeservices.css +378 -390
- package/examples/bootstrap/css/open-iconic.css +511 -511
- package/examples/bootstrap/fonts/open-iconic.svg +543 -543
- package/examples/bootstrap/js/compMessageDialog.js +20 -19
- package/examples/bootstrap/js/compSearchBar.js +12 -19
- package/examples/bootstrap/js/compSearchResults.js +50 -46
- package/examples/bootstrap/js/featureAdsResult.json +65 -65
- package/examples/bootstrap/js/searchResult.json +57 -57
- package/examples/bootstrap.html +343 -332
- package/examples/css/baseTodo.css +141 -141
- package/examples/css/dbMonsterStyles.css +27 -27
- package/examples/css/indexTodo.css +374 -374
- package/examples/dbmonsterForOfReactive.html +40 -0
- package/examples/dbmonsterReact.html +19 -0
- package/examples/forOfBindingSimpleDebug.html +45 -0
- package/examples/globalConfig.html +131 -0
- package/examples/js/afterRenderDemo.js +190 -0
- package/examples/js/appTodo.js +46 -46
- package/examples/js/attrBindingDemo.js +2 -2
- package/examples/js/dbMonApp.js +24 -26
- package/examples/js/dbMonAppReact.jsx +79 -0
- package/examples/js/dbMonAppReactive.js +28 -0
- package/examples/js/fiberDemo.js +4 -4
- package/examples/js/filtersDemo.js +8 -8
- package/examples/js/forOfDemo.js +7 -9
- package/examples/js/forOfDemoComplex.js +44 -17
- package/examples/js/form.js +14 -14
- package/examples/js/globalConfig.js +117 -0
- package/examples/js/ifBindingDemo.js +16 -16
- package/examples/js/reactiveDemo.js +119 -0
- package/examples/js/switchBindingDemo.js +8 -8
- package/examples/react-dbmonster/dist/bundle.js +43 -0
- package/examples/react-dbmonster/package-lock.json +537 -0
- package/examples/react-dbmonster/package.json +16 -0
- package/examples/react-dbmonster/src/index.jsx +80 -0
- package/examples/reactiveDemo.html +127 -0
- package/examples/refreshRateTest.html +75 -75
- package/index.html +841 -0
- package/package.json +31 -34
- package/rollup.config.js +79 -36
- package/src/{_escape.js → _escape.ts} +19 -17
- package/src/{applyBinding.js → applyBinding.ts} +27 -18
- package/src/{attrBinding.js → attrBinding.ts} +14 -13
- package/src/{binder.js → binder.ts} +289 -181
- package/src/changeBinding.ts +93 -0
- package/src/{commentWrapper.js → commentWrapper.ts} +33 -30
- package/src/config.ts +107 -0
- package/src/{createBindingOption.js → createBindingOption.ts} +39 -15
- package/src/createEventBinding.ts +88 -0
- package/src/{cssBinding.js → cssBinding.ts} +13 -11
- package/src/{domWalker.js → domWalker.ts} +44 -30
- package/src/{forOfBinding.js → forOfBinding.ts} +4 -3
- package/src/hoverBinding.ts +84 -0
- package/src/{ifBinding.js → ifBinding.ts} +14 -12
- package/src/index.ts +53 -0
- package/src/{modelBinding.js → modelBinding.ts} +11 -9
- package/src/{postProcess.js → postProcess.ts} +6 -4
- package/src/{pubSub.js → pubSub.ts} +24 -21
- package/src/reactiveProxy.ts +285 -0
- package/src/{renderForOfBinding.js → renderForOfBinding.ts} +54 -32
- package/src/{renderIfBinding.js → renderIfBinding.ts} +41 -19
- package/src/{renderIteration.js → renderIteration.ts} +24 -8
- package/src/renderTemplate.ts +165 -0
- package/src/renderTemplatesBinding.ts +73 -0
- package/src/{showBinding.js → showBinding.ts} +4 -3
- package/src/{switchBinding.js → switchBinding.ts} +18 -15
- package/src/{textBinding.js → textBinding.ts} +5 -4
- package/src/types.ts +124 -0
- package/src/util.ts +810 -0
- package/test/css/reporter.css +9 -9
- package/test/globals.d.ts +19 -0
- package/test/helpers/testHelper.js +46 -11
- package/test/mocks/featureAdsResult.json +65 -65
- package/test/mocks/searchResult.json +57 -57
- package/test/specs/{attrBinding.spec.js → attrBinding.spec.ts} +103 -106
- package/test/specs/{binder.spec.js → binder.spec.ts} +29 -27
- package/test/specs/blurBinding.spec.ts +60 -0
- package/test/specs/chainableUse.spec.ts +125 -0
- package/test/specs/clickBinding.spec.ts +194 -0
- package/test/specs/{cssBinding.spec.js → cssBinding.spec.ts} +72 -79
- package/test/specs/{dataBindBootstrap.spec.js → dataBindBootstrap.spec.ts} +332 -313
- package/test/specs/{filter.spec.js → filter.spec.ts} +75 -76
- package/test/specs/{forOfBinding.spec.js → forOfBinding.spec.ts} +208 -219
- package/test/specs/formBinding.spec.ts +272 -0
- package/test/specs/ifBinding.spec.ts +165 -0
- package/test/specs/{nestedComponent.spec.js → nestedComponent.spec.ts} +88 -88
- package/test/specs/reactiveProxy.spec.ts +465 -0
- package/test/specs/{showBinding.spec.js → showBinding.spec.ts} +148 -149
- package/test/specs/{switchBinding.spec.js → switchBinding.spec.ts} +172 -173
- package/test/specs/templateBinding.spec.ts +273 -0
- package/test/specs/{textBinding.spec.js → textBinding.spec.ts} +47 -48
- package/test/tsconfig.json +31 -0
- package/test-output.txt +200 -0
- package/test-reactive.html +224 -0
- package/tsconfig.json +28 -0
- package/vendors/lodash.custom.js +4577 -4577
- package/vendors/lodash.custom.min.js +45 -45
- package/vitest.config.js +27 -0
- package/.eslintrc.js +0 -1
- package/.grunt/grunt-contrib-jasmine/boot.js +0 -161
- package/.grunt/grunt-contrib-jasmine/dist/js/dataBind.js +0 -9
- package/.grunt/grunt-contrib-jasmine/grunt-template-jasmine-istanbul/reporter.js +0 -23
- package/.grunt/grunt-contrib-jasmine/jasmine-html.js +0 -853
- package/.grunt/grunt-contrib-jasmine/jasmine.css +0 -271
- package/.grunt/grunt-contrib-jasmine/jasmine.js +0 -9761
- package/.grunt/grunt-contrib-jasmine/jasmine_favicon.png +0 -0
- package/.grunt/grunt-contrib-jasmine/json2.js +0 -489
- package/.grunt/grunt-contrib-jasmine/reporter.js +0 -107
- package/coverage/coverage.json +0 -1
- package/coverage/lcov/lcov-report/base.css +0 -213
- package/coverage/lcov/lcov-report/index.html +0 -93
- package/coverage/lcov/lcov-report/js/dataBind.js.html +0 -6596
- package/coverage/lcov/lcov-report/js/index.html +0 -93
- package/coverage/lcov/lcov-report/prettify.css +0 -1
- package/coverage/lcov/lcov-report/prettify.js +0 -1
- package/coverage/lcov/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov/lcov-report/sorter.js +0 -158
- package/coverage/lcov/lcov.info +0 -1991
- package/eslintrc.json +0 -40
- package/examples/bootstrap/js/bootstrap.min.js +0 -6
- package/examples/bootstrap/js/popper.min.js +0 -5
- package/examples/bootstrap/js/searchSuggestion.js +0 -58
- package/examples/bootstrap/js/typeahead.jquery.js +0 -1538
- package/gruntfile.js +0 -92
- package/gulpfile.js +0 -32
- package/src/applyBindingExport.js +0 -5
- package/src/changeBinding.js +0 -63
- package/src/config.js +0 -66
- package/src/createEventBinding.js +0 -46
- package/src/eventSystem.js +0 -46
- package/src/hoverBinding.js +0 -57
- package/src/index.js +0 -26
- package/src/renderTemplate.js +0 -128
- package/src/renderTemplatesBinding.js +0 -44
- package/src/util.js +0 -648
- package/test/specs/blurBinding.spec.js +0 -57
- package/test/specs/formBinding.spec.js +0 -316
- package/test/specs/ifBinding.spec.js +0 -169
- package/test/specs/templateBinding.spec.js +0 -117
- package/vendors/jasmine-jquery.js +0 -841
- package/vendors/jquery-3.2.1.min.js +0 -4
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const { useState, useEffect, useRef } = React;
|
|
2
|
+
|
|
3
|
+
// Query component
|
|
4
|
+
function Query({ query }) {
|
|
5
|
+
return (
|
|
6
|
+
<td className={query.elapsedClassName}>
|
|
7
|
+
<span>{query.formatElapsed}</span>
|
|
8
|
+
<div className="popover left">
|
|
9
|
+
<div className="popover-content">{query.query}</div>
|
|
10
|
+
<div className="arrow"></div>
|
|
11
|
+
</div>
|
|
12
|
+
</td>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Database row component
|
|
17
|
+
function Database({ database }) {
|
|
18
|
+
return (
|
|
19
|
+
<tr>
|
|
20
|
+
<td className="dbname">{database.dbname}</td>
|
|
21
|
+
<td className="query-count">
|
|
22
|
+
<span className={database.lastSample.countClassName}>
|
|
23
|
+
{database.lastSample.nbQueries}
|
|
24
|
+
</span>
|
|
25
|
+
</td>
|
|
26
|
+
{database.lastSample.topFiveQueries.map((query, index) => (
|
|
27
|
+
<Query key={index} query={query} />
|
|
28
|
+
))}
|
|
29
|
+
</tr>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Main app component
|
|
34
|
+
function App() {
|
|
35
|
+
const [databases, setDatabases] = useState([]);
|
|
36
|
+
const performanceEnv = useRef(window.ENV);
|
|
37
|
+
const performanceMonitoring = useRef(window.Monitoring);
|
|
38
|
+
const timeoutId = useRef(null);
|
|
39
|
+
|
|
40
|
+
const refreshApp = () => {
|
|
41
|
+
const newData = performanceEnv.current.generateData().toArray();
|
|
42
|
+
setDatabases(newData);
|
|
43
|
+
|
|
44
|
+
performanceMonitoring.current.renderRate.ping();
|
|
45
|
+
timeoutId.current = setTimeout(refreshApp, performanceEnv.current.timeout);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
// Initial render
|
|
50
|
+
const initialData = performanceEnv.current.generateData().toArray();
|
|
51
|
+
setDatabases(initialData);
|
|
52
|
+
|
|
53
|
+
console.log('dbMonApp (React) initialized');
|
|
54
|
+
|
|
55
|
+
// Start the refresh loop
|
|
56
|
+
timeoutId.current = setTimeout(refreshApp, performanceEnv.current.timeout);
|
|
57
|
+
|
|
58
|
+
// Cleanup on unmount
|
|
59
|
+
return () => {
|
|
60
|
+
if (timeoutId.current) {
|
|
61
|
+
clearTimeout(timeoutId.current);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<table className="table table-striped latest-data">
|
|
68
|
+
<tbody>
|
|
69
|
+
{databases.map((database, index) => (
|
|
70
|
+
<Database key={index} database={database} />
|
|
71
|
+
))}
|
|
72
|
+
</tbody>
|
|
73
|
+
</table>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Render the app
|
|
78
|
+
const root = ReactDOM.createRoot(document.getElementById('app'));
|
|
79
|
+
root.render(<App />);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const performanceEnv = window.ENV;
|
|
2
|
+
const performanceMonitoring = window.Monitoring;
|
|
3
|
+
|
|
4
|
+
const viewModel = {
|
|
5
|
+
databases: performanceEnv.generateData().toArray(),
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// Reactive mode is enabled by default (no need to specify {reactive: true})
|
|
9
|
+
// This demo uses automatic reactive rendering for all updates
|
|
10
|
+
const dbMonApp = dataBind.init(document.getElementById('app'), viewModel);
|
|
11
|
+
|
|
12
|
+
function refreshApp() {
|
|
13
|
+
// Update via component.viewModel to trigger reactive updates
|
|
14
|
+
dbMonApp.viewModel.databases = performanceEnv.generateData().toArray();
|
|
15
|
+
|
|
16
|
+
// In reactive mode, render is triggered automatically
|
|
17
|
+
// No need to call render() manually!
|
|
18
|
+
|
|
19
|
+
performanceMonitoring.renderRate.ping();
|
|
20
|
+
setTimeout(refreshApp, performanceEnv.timeout);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// render().then() works with both reactive and manual modes
|
|
24
|
+
// The callback runs after the initial render completes
|
|
25
|
+
dbMonApp.render().then(() => {
|
|
26
|
+
console.log('dbMonApp (Reactive) inited');
|
|
27
|
+
refreshApp();
|
|
28
|
+
});
|
package/examples/js/fiberDemo.js
CHANGED
|
@@ -5,11 +5,11 @@ const fiberViewModel = {
|
|
|
5
5
|
dots: [],
|
|
6
6
|
dotCss: 'dot',
|
|
7
7
|
onHoverDot: {
|
|
8
|
-
in
|
|
8
|
+
in(e, $el, index) {
|
|
9
9
|
$el.style.background = '#ff0';
|
|
10
10
|
this.dots[index].isMouseOver = true;
|
|
11
11
|
},
|
|
12
|
-
out
|
|
12
|
+
out(e, $el, index) {
|
|
13
13
|
$el.style.background = '#61dafb';
|
|
14
14
|
this.dots[index].isMouseOver = false;
|
|
15
15
|
},
|
|
@@ -53,7 +53,7 @@ function createDot(x, y) {
|
|
|
53
53
|
|
|
54
54
|
function recursiveUpdateDotsData(viewModel) {
|
|
55
55
|
const remainder = getElapsedSecond() % 10;
|
|
56
|
-
const text = Math.floor(remainder)
|
|
56
|
+
const text = `${Math.floor(remainder) }`;
|
|
57
57
|
const scaleXFactor = (1 + (5 - Math.abs(5 - remainder)) / 10) / 2.1;
|
|
58
58
|
|
|
59
59
|
// update viewModel data
|
|
@@ -79,7 +79,7 @@ fiberViewModel.dots = createDotList();
|
|
|
79
79
|
// start binding on DOM ready
|
|
80
80
|
// formComponentC - test for-of binding
|
|
81
81
|
const fiberComponent = dataBind.init(document.querySelector('[data-bind-comp="fiberDemoComponent"]'), fiberViewModel);
|
|
82
|
-
fiberComponent.render().then(
|
|
82
|
+
fiberComponent.render().then(() => {
|
|
83
83
|
// for debug
|
|
84
84
|
console.log(fiberComponent);
|
|
85
85
|
window.fiberComponent = fiberComponent;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
(() => {
|
|
3
3
|
const filterComponentViewModel = {
|
|
4
4
|
renderIntro: true,
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
description:
|
|
13
13
|
'"Hansel and Gretel" (also known as Hansel and Grettel, Hansel and Grethel, or Little Brother and Little Sister) is a well-known fairy tale of German origin, recorded by the Brothers Grimm and published in 1812. Hansel and Gretel are a young brother and sister kidnapped by a cannibalistic witch living deep in the forest in a house constructed of cake and confectionery. The two children escape with their lives by outwitting her. The tale has been adapted to various media, most notably the opera Hänsel und Gretel (1893) by Engelbert Humperdinck. Under the Aarne–Thompson classification system, "Hansel and Gretel" is classified under Class 327.',
|
|
14
14
|
},
|
|
15
|
-
setStoryImgAttr
|
|
15
|
+
setStoryImgAttr() {
|
|
16
16
|
const picPath = this.story.pic || '';
|
|
17
17
|
const ret = {
|
|
18
18
|
alt: this.story.title,
|
|
@@ -25,20 +25,20 @@
|
|
|
25
25
|
}
|
|
26
26
|
return ret;
|
|
27
27
|
},
|
|
28
|
-
addPic
|
|
28
|
+
addPic(e) {
|
|
29
29
|
e.preventDefault();
|
|
30
30
|
this.story.pic = storyPic;
|
|
31
31
|
this.updateView();
|
|
32
32
|
},
|
|
33
|
-
removePic
|
|
33
|
+
removePic(e) {
|
|
34
34
|
e.preventDefault();
|
|
35
35
|
this.story.pic = '';
|
|
36
36
|
this.updateView();
|
|
37
37
|
},
|
|
38
|
-
toUpper
|
|
38
|
+
toUpper(strg) {
|
|
39
39
|
return strg.toUpperCase();
|
|
40
40
|
},
|
|
41
|
-
toDateFormat
|
|
41
|
+
toDateFormat(dateString) {
|
|
42
42
|
const date = new Date(dateString);
|
|
43
43
|
const monthNames = [
|
|
44
44
|
'January',
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
// start binding on DOM ready
|
|
72
72
|
|
|
73
73
|
// main
|
|
74
|
-
filterComponent = dataBind.init(document.querySelector('[data-bind-comp="filterComponent"]'), filterComponentViewModel);
|
|
75
|
-
filterComponent.render().then(
|
|
74
|
+
const filterComponent = dataBind.init(document.querySelector('[data-bind-comp="filterComponent"]'), filterComponentViewModel);
|
|
75
|
+
filterComponent.render().then(() => {
|
|
76
76
|
// for debug
|
|
77
77
|
console.log(filterComponent);
|
|
78
78
|
window.filterComponent = filterComponent;
|
package/examples/js/forOfDemo.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function() {
|
|
1
|
+
(function () {
|
|
2
2
|
// viewModel as Class for create multiple instance
|
|
3
3
|
class FormComponentVewModel {
|
|
4
4
|
constructor() {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
onInputChange(e, $el, newValue, oldValue, index) {
|
|
52
52
|
console.log('onInputChange: ', this);
|
|
53
53
|
this.personalDetails[index].show = false;
|
|
54
|
-
|
|
54
|
+
// Reactive mode - automatic render!
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
addRows(e) {
|
|
@@ -72,29 +72,27 @@
|
|
|
72
72
|
updatedCss: 'updated',
|
|
73
73
|
},
|
|
74
74
|
);
|
|
75
|
-
|
|
75
|
+
// Reactive mode - automatic render!
|
|
76
76
|
}
|
|
77
77
|
removeRows(e) {
|
|
78
78
|
e.preventDefault();
|
|
79
79
|
this.personalDetails.splice(this.personalDetails.length - 2, 2);
|
|
80
|
-
|
|
80
|
+
// Reactive mode - automatic render!
|
|
81
81
|
}
|
|
82
82
|
afterTemplateRender() {
|
|
83
83
|
console.log('template rendered');
|
|
84
84
|
}
|
|
85
|
-
updateView(opt) {
|
|
86
|
-
this.APP.render(opt);
|
|
87
|
-
}
|
|
88
85
|
}
|
|
89
86
|
|
|
90
87
|
// formComponentC viewModel
|
|
91
|
-
forOfComponentViewModel = new FormComponentVewModel();
|
|
88
|
+
const forOfComponentViewModel = new FormComponentVewModel();
|
|
92
89
|
|
|
93
90
|
// start binding on DOM ready
|
|
94
91
|
|
|
95
92
|
// formComponentC - test for-of binding
|
|
93
|
+
// Reactive mode is now the default!
|
|
96
94
|
const forOfComponent = dataBind.init(document.querySelector('[data-bind-comp="forOfComponent"]'), forOfComponentViewModel);
|
|
97
|
-
forOfComponent.render().then(
|
|
95
|
+
forOfComponent.render().then(() => {
|
|
98
96
|
// for debug
|
|
99
97
|
window.forOfComponent = forOfComponent;
|
|
100
98
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
// search-results-component
|
|
3
3
|
(() => {
|
|
4
4
|
const viewModel = {
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
options: [{text: '1', value: '1'}, {text: '2', value: '2'}, {text: '3', value: '3'}],
|
|
82
82
|
},
|
|
83
83
|
],
|
|
84
|
-
getResultItemAttr
|
|
84
|
+
getResultItemAttr(index, oldAttrObj, $el) {
|
|
85
85
|
const self = this;
|
|
86
86
|
if (self.searchResults[index].image) {
|
|
87
87
|
return {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
-
setResultOptionAttr
|
|
93
|
+
setResultOptionAttr($data, oldAttrObj, $el) {
|
|
94
94
|
if ($data && $data.value) {
|
|
95
95
|
// todo: the index here is the outter loop index
|
|
96
96
|
return {
|
|
@@ -98,21 +98,24 @@
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
},
|
|
101
|
-
onAdMessageCheck
|
|
101
|
+
onAdMessageCheck(e, $el, newValue, oldValue, index) {
|
|
102
102
|
console.log('onAdMessageCheck: ', $el, newValue, oldValue, index);
|
|
103
103
|
},
|
|
104
|
-
onAdBookmarkClick
|
|
104
|
+
onAdBookmarkClick(e, $el, index) {
|
|
105
105
|
e.preventDefault();
|
|
106
106
|
console.log('onAdBookmarkClick: ', $el, index);
|
|
107
107
|
},
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
+
// Default mutations count, controlled by slider
|
|
111
|
+
let mutationsCount = 50;
|
|
112
|
+
|
|
110
113
|
const generateRamdomData = () => {
|
|
111
114
|
const data = [];
|
|
112
115
|
const getRandomNumber = (x, y) => {
|
|
113
116
|
return Math.floor(Math.random() * (y - x + 1) + x);
|
|
114
117
|
};
|
|
115
|
-
const randomSeed =
|
|
118
|
+
const randomSeed = mutationsCount;
|
|
116
119
|
const images = [
|
|
117
120
|
'bootstrap/images/pic-home.jpg',
|
|
118
121
|
'bootstrap/images/pic-carpenter.jpg',
|
|
@@ -132,7 +135,7 @@
|
|
|
132
135
|
for (let i = 0; i < randomSeed; i += 1) {
|
|
133
136
|
data.push({
|
|
134
137
|
id: i,
|
|
135
|
-
title:
|
|
138
|
+
title: `Sample gardening service${ i}`,
|
|
136
139
|
description: descriptions[getRandomNumber(0, descriptions.length - 1)],
|
|
137
140
|
image: images[getRandomNumber(0, images.length - 1)],
|
|
138
141
|
bookmarked: false,
|
|
@@ -145,34 +148,58 @@
|
|
|
145
148
|
};
|
|
146
149
|
|
|
147
150
|
const updateResults = () => {
|
|
148
|
-
window.updateInterval = setInterval(
|
|
149
|
-
viewModel
|
|
150
|
-
searchResultsComponent.
|
|
151
|
+
window.updateInterval = setInterval(() => {
|
|
152
|
+
// Important: Use searchResultsComponent.viewModel (proxied version) for reactive updates
|
|
153
|
+
searchResultsComponent.viewModel.searchResults = generateRamdomData();
|
|
154
|
+
// Automatic render happens via reactive proxy!
|
|
155
|
+
|
|
156
|
+
// Note: In reactive mode, render is called automatically.
|
|
157
|
+
// For monitoring, we manually trigger render().then() to get the promise callback
|
|
158
|
+
// This is safe because render() is debounced - it won't cause double rendering
|
|
159
|
+
if (typeof Monitoring !== 'undefined') {
|
|
160
|
+
searchResultsComponent.render().then(() => {
|
|
161
|
+
Monitoring.renderRate.ping();
|
|
162
|
+
});
|
|
163
|
+
}
|
|
151
164
|
});
|
|
152
165
|
};
|
|
153
166
|
|
|
154
167
|
// start binding on DOM ready
|
|
155
168
|
|
|
156
|
-
// debug
|
|
157
|
-
const searchResultsComponent = dataBind.init(
|
|
169
|
+
// debug - Reactive mode is now the default!
|
|
170
|
+
const searchResultsComponent = dataBind.init(
|
|
171
|
+
document.querySelector('[data-bind-comp="search-results-component"]'),
|
|
172
|
+
viewModel
|
|
173
|
+
);
|
|
158
174
|
|
|
159
|
-
searchResultsComponent.render().then(
|
|
175
|
+
searchResultsComponent.render().then(() => {
|
|
160
176
|
// for debug
|
|
161
177
|
console.log(searchResultsComponent);
|
|
162
178
|
window.searchResultsComponent = searchResultsComponent;
|
|
163
179
|
|
|
164
|
-
btnRandomRender = document.getElementById('btnRandomRender');
|
|
165
|
-
btnStopRandomRender = document.getElementById('btnStopRandomRender');
|
|
180
|
+
const btnRandomRender = document.getElementById('btnRandomRender');
|
|
181
|
+
const btnStopRandomRender = document.getElementById('btnStopRandomRender');
|
|
166
182
|
|
|
167
|
-
btnRandomRender.addEventListener('click',
|
|
183
|
+
btnRandomRender.addEventListener('click', (e) => {
|
|
168
184
|
e.preventDefault();
|
|
169
185
|
clearInterval(window.updateInterval);
|
|
170
186
|
updateResults();
|
|
171
187
|
}, false);
|
|
172
188
|
|
|
173
|
-
btnStopRandomRender.addEventListener('click',
|
|
189
|
+
btnStopRandomRender.addEventListener('click', (e) => {
|
|
174
190
|
e.preventDefault();
|
|
175
191
|
clearInterval(window.updateInterval);
|
|
176
192
|
}, false);
|
|
193
|
+
|
|
194
|
+
// Connect mutations slider to control item count
|
|
195
|
+
const mutationsSlider = document.getElementById('mutations');
|
|
196
|
+
const mutationsValueSpan = document.getElementById('mutationsValue');
|
|
197
|
+
|
|
198
|
+
if (mutationsSlider && mutationsValueSpan) {
|
|
199
|
+
mutationsSlider.addEventListener('input', (e) => {
|
|
200
|
+
mutationsCount = parseInt(e.target.value, 10);
|
|
201
|
+
mutationsValueSpan.textContent = mutationsCount;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
177
204
|
});
|
|
178
205
|
})();
|
package/examples/js/form.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(() =>{
|
|
1
|
+
(() => {
|
|
2
2
|
const formAppViewModel = {
|
|
3
3
|
intro: {
|
|
4
4
|
title: 'Form generator demo',
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
And finally a quick test of attribute binding 😎`,
|
|
11
11
|
btnText: 'Fake button »',
|
|
12
12
|
},
|
|
13
|
-
onBtnClick
|
|
13
|
+
onBtnClick(e, $el) {
|
|
14
14
|
e.preventDefault();
|
|
15
15
|
console.log('onBtnClick: ', $el);
|
|
16
16
|
},
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
onInputChange(e, $el, newValue, oldValue) {
|
|
40
40
|
console.log('onInputChange: ', this);
|
|
41
41
|
this.personalDetails[0].show = false;
|
|
42
|
-
|
|
42
|
+
// Reactive mode - automatic render!
|
|
43
43
|
}
|
|
44
44
|
afterTemplateRender() {
|
|
45
45
|
console.log('template rendered');
|
|
46
46
|
}
|
|
47
|
-
updateView(opt) {
|
|
48
|
-
|
|
47
|
+
updateView(opt) { // Note: render is automatic in reactive mode
|
|
48
|
+
// Reactive mode - automatic render!
|
|
49
49
|
}
|
|
50
50
|
getInputAttr(index) {
|
|
51
51
|
const personalDetail = this.personalDetails[index];
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
range: {
|
|
83
83
|
value: 50,
|
|
84
84
|
},
|
|
85
|
-
getRangeAttr
|
|
85
|
+
getRangeAttr() {
|
|
86
86
|
return {
|
|
87
87
|
type: 'range',
|
|
88
88
|
name: 'test-range',
|
|
@@ -92,13 +92,13 @@
|
|
|
92
92
|
step: 1,
|
|
93
93
|
};
|
|
94
94
|
},
|
|
95
|
-
onInputChange
|
|
95
|
+
onInputChange(e, $el, newValue, oldValue) {
|
|
96
96
|
e.preventDefault();
|
|
97
97
|
this.range.value = newValue;
|
|
98
|
-
|
|
98
|
+
// Reactive mode - automatic render!
|
|
99
99
|
},
|
|
100
|
-
updateView(opt) {
|
|
101
|
-
|
|
100
|
+
updateView(opt) { // Note: render is automatic in reactive mode
|
|
101
|
+
// Reactive mode - automatic render!
|
|
102
102
|
},
|
|
103
103
|
};
|
|
104
104
|
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
|
|
107
107
|
// main formApp
|
|
108
108
|
const formApp = dataBind.init(document.querySelector('[data-bind-comp="formApp"]'), formAppViewModel);
|
|
109
|
-
formApp.render().then(
|
|
109
|
+
formApp.render().then(() => {
|
|
110
110
|
// for debug
|
|
111
111
|
console.log(formApp);
|
|
112
112
|
window.formApp = formApp;
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
// formComponentA
|
|
116
116
|
const formComponentA = dataBind.init(document.querySelector('[data-bind-comp="formComponentA"]'), new FormComponentVewModel());
|
|
117
117
|
|
|
118
|
-
formComponentA.render().then(
|
|
118
|
+
formComponentA.render().then(() => {
|
|
119
119
|
// for debug
|
|
120
120
|
console.log(formComponentA);
|
|
121
121
|
window.formComponentA = formComponentA;
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
// formComponentB
|
|
125
125
|
const formComponentB = dataBind.init(document.querySelector('[data-bind-comp="formComponentB"]'), formComponentBViewModel);
|
|
126
126
|
|
|
127
|
-
formComponentB.render().then(
|
|
127
|
+
formComponentB.render().then(() => {
|
|
128
128
|
// for debug
|
|
129
129
|
console.log(formComponentB);
|
|
130
130
|
window.formComponentB = formComponentB;
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
// componentRangeInput
|
|
134
134
|
const componentRangeInput = dataBind.init(document.querySelector('[data-bind-comp="componentRangeInput"]'), componentRangeInputViewModel);
|
|
135
135
|
|
|
136
|
-
componentRangeInput.render().then(
|
|
136
|
+
componentRangeInput.render().then(() => {
|
|
137
137
|
// for debug
|
|
138
138
|
console.log(componentRangeInput);
|
|
139
139
|
window.componentRangeInput = componentRangeInput;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
console.log('=== Global Configuration Demo ===');
|
|
3
|
+
|
|
4
|
+
// Example 1: Default configuration (reactive: true is built-in default)
|
|
5
|
+
console.log('\n1. Creating component with default config (reactive: true)');
|
|
6
|
+
const defaultExample = dataBind.init(
|
|
7
|
+
document.querySelector('[data-bind-comp="default-example"]'),
|
|
8
|
+
{
|
|
9
|
+
counter: 0,
|
|
10
|
+
increment() {
|
|
11
|
+
this.counter++;
|
|
12
|
+
// Reactive mode - automatic render!
|
|
13
|
+
},
|
|
14
|
+
reset() {
|
|
15
|
+
this.counter = 0;
|
|
16
|
+
// Reactive mode - automatic render!
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
defaultExample.render().then(() => {
|
|
22
|
+
console.log('Example 1 initialized - Mode:', defaultExample.isReactive ? 'REACTIVE' : 'MANUAL');
|
|
23
|
+
document.getElementById('mode1').textContent = defaultExample.isReactive ? 'REACTIVE ✅' : 'MANUAL';
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Change global configuration to manual mode
|
|
27
|
+
console.log('\n2. Calling dataBind.use({ reactive: false })');
|
|
28
|
+
dataBind.use({
|
|
29
|
+
reactive: false,
|
|
30
|
+
});
|
|
31
|
+
console.log('Global default is now: reactive = false');
|
|
32
|
+
|
|
33
|
+
// Example 2: Component created after use() call - uses manual mode
|
|
34
|
+
console.log('\n3. Creating component after use() call (should use manual mode)');
|
|
35
|
+
const globalManualExample = dataBind.init(
|
|
36
|
+
document.querySelector('[data-bind-comp="global-manual"]'),
|
|
37
|
+
{
|
|
38
|
+
counter: 0,
|
|
39
|
+
increment() {
|
|
40
|
+
this.counter++;
|
|
41
|
+
// Manual mode - need to call render()
|
|
42
|
+
globalManualExample.render();
|
|
43
|
+
},
|
|
44
|
+
reset() {
|
|
45
|
+
this.counter = 0;
|
|
46
|
+
// Manual mode - need to call render()
|
|
47
|
+
globalManualExample.render();
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
globalManualExample.render().then(() => {
|
|
53
|
+
console.log('Example 2 initialized - Mode:', globalManualExample.isReactive ? 'REACTIVE' : 'MANUAL');
|
|
54
|
+
document.getElementById('mode2').textContent = globalManualExample.isReactive ? 'REACTIVE' : 'MANUAL ✅';
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Example 3: Chainable API
|
|
58
|
+
console.log('\n4. Creating component with chainable API: dataBind.use({reactive: false}).init(...)');
|
|
59
|
+
const chainableExample = dataBind.use({reactive: false}).init(
|
|
60
|
+
document.querySelector('[data-bind-comp="chainable"]'),
|
|
61
|
+
{
|
|
62
|
+
counter: 0,
|
|
63
|
+
increment() {
|
|
64
|
+
this.counter++;
|
|
65
|
+
// Manual mode - need to call render()
|
|
66
|
+
chainableExample.render();
|
|
67
|
+
},
|
|
68
|
+
reset() {
|
|
69
|
+
this.counter = 0;
|
|
70
|
+
// Manual mode - need to call render()
|
|
71
|
+
chainableExample.render();
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
chainableExample.render().then(() => {
|
|
77
|
+
console.log('Example 3 initialized - Mode:', chainableExample.isReactive ? 'REACTIVE' : 'MANUAL');
|
|
78
|
+
document.getElementById('mode3').textContent = chainableExample.isReactive ? 'REACTIVE' : 'MANUAL ✅ (chained)';
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Example 4: Override global setting with instance option
|
|
82
|
+
console.log('\n5. Creating component with instance override { reactive: true }');
|
|
83
|
+
const instanceOverride = dataBind.init(
|
|
84
|
+
document.querySelector('[data-bind-comp="instance-override"]'),
|
|
85
|
+
{
|
|
86
|
+
counter: 0,
|
|
87
|
+
increment() {
|
|
88
|
+
this.counter++;
|
|
89
|
+
// Reactive mode - automatic render! (overridden)
|
|
90
|
+
},
|
|
91
|
+
reset() {
|
|
92
|
+
this.counter = 0;
|
|
93
|
+
// Reactive mode - automatic render! (overridden)
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{reactive: true}, // Instance override
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
instanceOverride.render().then(() => {
|
|
100
|
+
console.log('Example 4 initialized - Mode:', instanceOverride.isReactive ? 'REACTIVE' : 'MANUAL');
|
|
101
|
+
document.getElementById('mode4').textContent = instanceOverride.isReactive ? 'REACTIVE ✅ (overridden)' : 'MANUAL';
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
console.log('\n=== Summary ===');
|
|
105
|
+
console.log('Example 1: Created before use() call → REACTIVE (built-in default)');
|
|
106
|
+
console.log('Example 2: Created after use({reactive: false}) → MANUAL (global default)');
|
|
107
|
+
console.log('Example 3: Created with chainable API → MANUAL (chained use)');
|
|
108
|
+
console.log('Example 4: Created with {reactive: true} → REACTIVE (instance override)');
|
|
109
|
+
|
|
110
|
+
// Debug access
|
|
111
|
+
window.configExamples = {
|
|
112
|
+
default: defaultExample,
|
|
113
|
+
globalManual: globalManualExample,
|
|
114
|
+
chainable: chainableExample,
|
|
115
|
+
instanceOverride: instanceOverride,
|
|
116
|
+
};
|
|
117
|
+
})();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
(() => {
|
|
3
3
|
const myComponentViewModel = {
|
|
4
4
|
renderIntro: false,
|
|
@@ -13,36 +13,36 @@
|
|
|
13
13
|
{title: 'The Ugly Duckling', value: 's2'},
|
|
14
14
|
{title: 'The Giving Tree', value: 's3'},
|
|
15
15
|
],
|
|
16
|
-
setStoryOptionAttr
|
|
16
|
+
setStoryOptionAttr($data, oldAttrObj, $el) {
|
|
17
17
|
if ($data && $data.value) {
|
|
18
18
|
return {
|
|
19
19
|
value: $data.value,
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
-
onSelectedStory
|
|
23
|
+
onSelectedStory(e, $el, newValue, oldValue) {
|
|
24
24
|
e.preventDefault();
|
|
25
25
|
this.APP.publish('SELECTED_STORY', newValue);
|
|
26
26
|
},
|
|
27
|
-
renderItem
|
|
27
|
+
renderItem(e, $el) {
|
|
28
28
|
e.preventDefault();
|
|
29
29
|
this.renderIntro = true;
|
|
30
|
-
|
|
30
|
+
// Reactive mode - automatic render!
|
|
31
31
|
},
|
|
32
|
-
removeItem
|
|
32
|
+
removeItem(e, $el) {
|
|
33
33
|
e.preventDefault();
|
|
34
34
|
this.renderIntro = false;
|
|
35
|
-
|
|
35
|
+
// Reactive mode - automatic render!
|
|
36
36
|
},
|
|
37
|
-
updateView(opt) {
|
|
38
|
-
|
|
37
|
+
updateView(opt) { // Note: render is automatic in reactive mode
|
|
38
|
+
// Reactive mode - automatic render!
|
|
39
39
|
},
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
const compStoryDetailViewModel = {
|
|
43
43
|
selectedStory: '',
|
|
44
44
|
story: {},
|
|
45
|
-
setStoryImgAttr
|
|
45
|
+
setStoryImgAttr() {
|
|
46
46
|
const picPath = this.story.pic || '';
|
|
47
47
|
const ret = {
|
|
48
48
|
alt: this.story.title,
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
}
|
|
56
56
|
return ret;
|
|
57
57
|
},
|
|
58
|
-
onStoryChange
|
|
58
|
+
onStoryChange(id) {
|
|
59
59
|
if (storiesData[id] && id !== this.selectedStory) {
|
|
60
60
|
this.story = storiesData[id];
|
|
61
61
|
this.selectedStory = id;
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
this.story = '';
|
|
64
64
|
this.selectedStory = '';
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
// Reactive mode - automatic render!
|
|
67
67
|
},
|
|
68
|
-
updateView(opt) {
|
|
69
|
-
|
|
68
|
+
updateView(opt) { // Note: render is automatic in reactive mode
|
|
69
|
+
// Reactive mode - automatic render!
|
|
70
70
|
},
|
|
71
71
|
};
|
|
72
72
|
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
|
|
97
97
|
// main
|
|
98
98
|
const myComponent = dataBind.init(document.querySelector('[data-bind-comp="myComponent"]'), myComponentViewModel);
|
|
99
|
-
myComponent.render().then(
|
|
99
|
+
myComponent.render().then(() => {
|
|
100
100
|
// for debug
|
|
101
101
|
console.log(myComponent);
|
|
102
102
|
window.myComponent = myComponent;
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
|
|
105
105
|
// story detail componenet
|
|
106
106
|
const compStoryDetail = dataBind.init(document.querySelector('[data-bind-comp="compStoryDetail"]'), compStoryDetailViewModel);
|
|
107
|
-
compStoryDetail.render().then(
|
|
107
|
+
compStoryDetail.render().then((thisComponent) => {
|
|
108
108
|
thisComponent.subscribe('SELECTED_STORY', thisComponent.viewModel.onStoryChange);
|
|
109
109
|
// for debug
|
|
110
110
|
console.log(compStoryDetail);
|