neo.mjs 10.0.0-alpha.4 → 10.0.0-beta.1
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/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/resources/data/examples_devmode.json +26 -27
- package/apps/portal/resources/data/examples_dist_dev.json +26 -27
- package/apps/portal/resources/data/examples_dist_esm.json +26 -27
- package/apps/portal/resources/data/examples_dist_prod.json +27 -28
- package/apps/portal/view/blog/List.mjs +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/portal/view/learn/ContentComponent.mjs +102 -111
- package/buildScripts/buildThemes.mjs +1 -1
- package/examples/grid/animatedRowSorting/Viewport.mjs +4 -4
- package/examples/grid/bigData/ControlsContainer.mjs +3 -3
- package/examples/grid/bigData/GridContainer.mjs +8 -8
- package/examples/grid/cellEditing/MainContainer.mjs +5 -5
- package/examples/grid/container/MainContainer.mjs +4 -4
- package/examples/grid/nestedRecordFields/Viewport.mjs +5 -5
- package/examples/table/cellEditing/MainContainer.mjs +1 -1
- package/examples/table/container/MainContainer.mjs +3 -3
- package/examples/table/nestedRecordFields/Viewport.mjs +6 -6
- package/examples/tableFiltering/MainContainer.mjs +1 -1
- package/examples/tablePerformance/MainContainer.mjs +1 -1
- package/examples/tablePerformance/MainContainer2.mjs +1 -1
- package/examples/tablePerformance/MainContainer3.mjs +2 -2
- package/examples/tableStore/MainContainer.mjs +2 -2
- package/learn/UsingTheseTopics.md +2 -2
- package/learn/benefits/ConfigSystem.md +2 -2
- package/learn/benefits/FormsEngine.md +14 -14
- package/learn/benefits/MultiWindow.md +2 -2
- package/learn/benefits/OffTheMainThread.md +2 -2
- package/learn/benefits/Speed.md +2 -2
- package/learn/gettingstarted/ComponentModels.md +4 -4
- package/learn/gettingstarted/Config.md +6 -6
- package/learn/gettingstarted/DescribingTheUI.md +4 -4
- package/learn/gettingstarted/Events.md +6 -6
- package/learn/gettingstarted/Extending.md +4 -4
- package/learn/gettingstarted/References.md +6 -6
- package/learn/gettingstarted/Workspaces.md +6 -6
- package/learn/guides/ApplicationBootstrap.md +40 -42
- package/learn/guides/ComponentsAndContainers.md +12 -12
- package/learn/guides/CustomComponents.md +2 -2
- package/learn/guides/MainThreadAddonIntro.md +2 -2
- package/learn/guides/PortalApp.md +2 -2
- package/learn/guides/StateProviders.md +12 -12
- package/learn/guides/events/CustomEvents.md +16 -16
- package/learn/guides/events/DomEvents.md +12 -12
- package/learn/javascript/ClassFeatures.md +3 -2
- package/learn/javascript/Classes.md +8 -8
- package/learn/javascript/NewNode.md +4 -4
- package/learn/javascript/Overrides.md +8 -8
- package/learn/javascript/Super.md +10 -8
- package/learn/tutorials/Earthquakes.md +54 -57
- package/learn/tutorials/TodoList.md +4 -4
- package/package.json +1 -1
- package/resources/scss/src/apps/portal/learn/ContentComponent.scss +12 -0
- package/resources/scss/src/grid/{View.scss → Body.scss} +2 -2
- package/resources/scss/src/grid/VerticalScrollbar.scss +1 -1
- package/resources/scss/src/grid/plugin/AnimateRows.scss +1 -1
- package/resources/scss/src/grid/plugin/CellEditing.scss +1 -1
- package/resources/scss/src/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/src/table/plugin/CellEditing.scss +1 -1
- package/resources/scss/theme-dark/grid/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-dark/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-light/grid/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-light/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-neo-light/Global.scss +1 -2
- package/resources/scss/theme-neo-light/grid/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-neo-light/table/{View.scss → Body.scss} +1 -1
- package/src/DefaultConfig.mjs +2 -2
- package/src/core/Base.mjs +59 -12
- package/src/core/Util.mjs +14 -2
- package/src/draggable/grid/header/toolbar/SortZone.mjs +21 -21
- package/src/draggable/table/header/toolbar/SortZone.mjs +1 -1
- package/src/grid/{View.mjs → Body.mjs} +19 -20
- package/src/grid/Container.mjs +58 -58
- package/src/grid/ScrollManager.mjs +56 -56
- package/src/grid/VerticalScrollbar.mjs +2 -2
- package/src/grid/_export.mjs +2 -2
- package/src/grid/column/AnimatedChange.mjs +5 -5
- package/src/grid/column/Base.mjs +1 -1
- package/src/grid/column/Component.mjs +6 -6
- package/src/grid/header/Toolbar.mjs +9 -9
- package/src/grid/plugin/AnimateRows.mjs +1 -2
- package/src/main/addon/AmCharts.mjs +8 -11
- package/src/main/addon/Base.mjs +150 -42
- package/src/main/addon/GoogleMaps.mjs +9 -16
- package/src/main/addon/HighlightJS.mjs +2 -13
- package/src/main/addon/IntersectionObserver.mjs +21 -21
- package/src/main/addon/MonacoEditor.mjs +1 -6
- package/src/table/{View.mjs → Body.mjs} +19 -20
- package/src/table/Container.mjs +43 -43
- package/src/table/_export.mjs +2 -2
- package/src/table/plugin/CellEditing.mjs +19 -19
- package/src/util/Style.mjs +2 -6
- package/src/vdom/Helper.mjs +10 -13
- package/src/worker/App.mjs +6 -18
- package/src/worker/Base.mjs +1 -1
- package/src/worker/Manager.mjs +4 -8
- package/src/worker/mixin/RemoteMethodAccess.mjs +1 -1
@@ -40,17 +40,17 @@ class Viewport extends BaseViewport {
|
|
40
40
|
module: TableContainer,
|
41
41
|
bind : {store : 'stores.mainStore'},
|
42
42
|
|
43
|
+
bodyConfig: {
|
44
|
+
highlightModifiedCells: true
|
45
|
+
},
|
46
|
+
|
43
47
|
columns: [
|
44
48
|
{dataField: 'user.firstname', text: 'Firstname'},
|
45
49
|
{dataField: 'user.lastname', text: 'Lastname'},
|
46
50
|
{dataField: 'githubId', text: 'Github Id'},
|
47
51
|
{dataField: 'country', text: 'Country', renderer: 'up.countryRenderer'},
|
48
52
|
{dataField: 'edit', text: 'Edit Action', renderer: 'up.editRenderer'}
|
49
|
-
]
|
50
|
-
|
51
|
-
viewConfig: {
|
52
|
-
highlightModifiedCells: true
|
53
|
-
}
|
53
|
+
]
|
54
54
|
}]
|
55
55
|
}
|
56
56
|
|
@@ -118,7 +118,7 @@ class Viewport extends BaseViewport {
|
|
118
118
|
windowId
|
119
119
|
}));
|
120
120
|
|
121
|
-
me.
|
121
|
+
me.body.updateDepth = -1;
|
122
122
|
|
123
123
|
return button.createVdomReference()
|
124
124
|
}
|
@@ -46,10 +46,10 @@ class MainContainer extends Viewport {
|
|
46
46
|
}]
|
47
47
|
}, {
|
48
48
|
module : TableContainer,
|
49
|
+
bodyConfig : {selectionModel: CellModel},
|
49
50
|
id : 'myTableFilterContainer',
|
50
51
|
showHeaderFilters: true,
|
51
52
|
store : MainStore,
|
52
|
-
viewConfig : {selectionModel: CellModel},
|
53
53
|
width : '100%',
|
54
54
|
wrapperStyle : {height: '300px'},
|
55
55
|
|
@@ -72,8 +72,8 @@ class MainContainer3 extends Container {
|
|
72
72
|
}]
|
73
73
|
}, {
|
74
74
|
module : TableContainer,
|
75
|
+
bodyConfig : {useRowRecordIds: false},
|
75
76
|
reference : 'table',
|
76
|
-
viewConfig : {useRowRecordIds: false},
|
77
77
|
useCustomScrollbars: false,
|
78
78
|
width : '100%',
|
79
79
|
|
@@ -146,7 +146,7 @@ class MainContainer3 extends Container {
|
|
146
146
|
rows = me.getReference('amount-rows-field').value,
|
147
147
|
inputData = me.up('viewport').createRandomData(columns, rows);
|
148
148
|
|
149
|
-
table.
|
149
|
+
table.body.createViewData(inputData)
|
150
150
|
}
|
151
151
|
|
152
152
|
/**
|
@@ -151,10 +151,10 @@ class MainContainer extends Viewport {
|
|
151
151
|
}]
|
152
152
|
}, {
|
153
153
|
module : TableContainer,
|
154
|
+
bodyConfig : {selectionModel: CellModel},
|
154
155
|
id : 'myTableStoreContainer',
|
155
156
|
reference : 'table',
|
156
157
|
store : MainStore,
|
157
|
-
viewConfig : {selectionModel: CellModel},
|
158
158
|
width : '100%',
|
159
159
|
wrapperStyle: {height: '300px'},
|
160
160
|
|
@@ -179,7 +179,7 @@ class MainContainer extends Viewport {
|
|
179
179
|
*/
|
180
180
|
updateSelectionModel(data) {
|
181
181
|
if (data.value) {
|
182
|
-
this.getReference('table').
|
182
|
+
this.getReference('table').body.selectionModel = {
|
183
183
|
ntype: data.component.value
|
184
184
|
}
|
185
185
|
}
|
@@ -41,7 +41,7 @@ You can also launch the preview in a window by going to the Preview tab, then cl
|
|
41
41
|
icon on the right <span class="far fa-xs fa-window-maximize"></span>. This web site is a Neo.mjs application,
|
42
42
|
and the ability to launch browser windows — all integrated within a single app — is a unique feature of Neo.mjs!
|
43
43
|
|
44
|
-
|
44
|
+
```javascript live-preview
|
45
45
|
import Button from '../button/Base.mjs';
|
46
46
|
import Container from '../container/Base.mjs';
|
47
47
|
|
@@ -57,7 +57,7 @@ class MainView extends Container {
|
|
57
57
|
}
|
58
58
|
|
59
59
|
MainView = Neo.setupClass(MainView);
|
60
|
-
|
60
|
+
```
|
61
61
|
|
62
62
|
---
|
63
63
|
|
@@ -10,7 +10,7 @@ and nested approach to their configuration, a gap that a class config system aim
|
|
10
10
|
## A bad example
|
11
11
|
I recently found this Angular code snippet (new public API draft) on LinkedIn:
|
12
12
|
|
13
|
-
|
13
|
+
```javascript readonly
|
14
14
|
// MyComponent with an attribute
|
15
15
|
<MyComponent myAttribute="someValue" />
|
16
16
|
|
@@ -25,7 +25,7 @@ I recently found this Angular code snippet (new public API draft) on LinkedIn:
|
|
25
25
|
|
26
26
|
// Scoped inputs for MyDirective
|
27
27
|
<MyComponent @MyDirective(input1="someString" [input2]="mySignal()") />
|
28
|
-
|
28
|
+
```
|
29
29
|
|
30
30
|
Now you might wonder why I think that this is not a good way to create apps.
|
31
31
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
You do not need to define a state tree on your own.
|
4
4
|
It is sufficient to just use namespaces inside the `name` attribute of each field.
|
5
5
|
|
6
|
-
|
6
|
+
```javascript live-preview
|
7
7
|
import Button from '../button/Base.mjs';
|
8
8
|
import FormContainer from '../form/Container.mjs';
|
9
9
|
import TextField from '../form/field/Text.mjs';
|
@@ -38,7 +38,7 @@ class MainView extends FormContainer {
|
|
38
38
|
}
|
39
39
|
}
|
40
40
|
MainView = Neo.setupClass(MainView);
|
41
|
-
|
41
|
+
```
|
42
42
|
|
43
43
|
## Forms can get validated without being mounted
|
44
44
|
|
@@ -49,7 +49,7 @@ Getting the field values still works like before.
|
|
49
49
|
Use case: In case you have a form split into multiple pages and only one of them is mounted to keep
|
50
50
|
the DOM minimal, you can still get all field values.
|
51
51
|
|
52
|
-
|
52
|
+
```javascript live-preview
|
53
53
|
import Button from '../button/Base.mjs';
|
54
54
|
import Container from '../container/Base.mjs';
|
55
55
|
import FormContainer from '../form/Container.mjs';
|
@@ -89,7 +89,7 @@ class MainView extends Container {
|
|
89
89
|
}
|
90
90
|
}
|
91
91
|
MainView = Neo.setupClass(MainView);
|
92
|
-
|
92
|
+
```
|
93
93
|
|
94
94
|
## Nested Forms
|
95
95
|
|
@@ -104,28 +104,28 @@ Inside the example preview, clear the user lastname via hitting the x-button.
|
|
104
104
|
Afterwards, click on the 3 buttons at the bottom and inspect the output inside the main window console carefully.
|
105
105
|
|
106
106
|
The main form will log:
|
107
|
-
|
107
|
+
```javascript readonly
|
108
108
|
{
|
109
109
|
account: 'My Account',
|
110
110
|
product: {brand: 'Tesla', name: 'Car'},
|
111
111
|
user : {firstname: 'John', lastname: null}
|
112
112
|
}
|
113
113
|
'isValid: false'
|
114
|
-
|
114
|
+
```
|
115
115
|
|
116
116
|
The user form will log:
|
117
|
-
|
117
|
+
```javascript readonly
|
118
118
|
{user: {firstname: 'John', lastname: null}}
|
119
119
|
'isValid: false'
|
120
|
-
|
120
|
+
```
|
121
121
|
|
122
122
|
The product form will log:
|
123
|
-
|
123
|
+
```javascript readonly
|
124
124
|
{product: {brand: 'Tesla', name: 'Car'}}
|
125
125
|
'isValid: true'
|
126
|
-
|
126
|
+
```
|
127
127
|
|
128
|
-
|
128
|
+
```javascript live-preview
|
129
129
|
import Button from '../button/Base.mjs';
|
130
130
|
import Container from '../container/Base.mjs';
|
131
131
|
import FormContainer from '../form/Container.mjs';
|
@@ -223,7 +223,7 @@ class MainView extends FormContainer {
|
|
223
223
|
}
|
224
224
|
}
|
225
225
|
MainView = Neo.setupClass(MainView);
|
226
|
-
|
226
|
+
```
|
227
227
|
|
228
228
|
Bonus: Inspect the DOM Inside the `TabContainer`.
|
229
229
|
You will notice that only the active Tab is mounted inside the DOM.
|
@@ -244,7 +244,7 @@ since it does rely on defining child modules inside their own class files
|
|
244
244
|
and dynamically importing them.
|
245
245
|
|
246
246
|
In a nutshell:
|
247
|
-
|
247
|
+
```javascript readonly
|
248
248
|
{
|
249
249
|
module: TabContainer,
|
250
250
|
items : [
|
@@ -252,4 +252,4 @@ In a nutshell:
|
|
252
252
|
{module: () => import('./MyChildForm2.mjs')}
|
253
253
|
]
|
254
254
|
}
|
255
|
-
|
255
|
+
```
|
@@ -14,7 +14,7 @@ running the code. Even though it's running in a new window, it's still part of t
|
|
14
14
|
(In this case, the app is the web site you're looking at now.) That means both the code in both windows
|
15
15
|
seamlessly share events, data, etc. — the code doesn't care that some code is running in a
|
16
16
|
separate window.
|
17
|
-
|
17
|
+
```javascript live-preview
|
18
18
|
import Button from '../button/Base.mjs';
|
19
19
|
import Container from '../container/Base.mjs';
|
20
20
|
|
@@ -31,6 +31,6 @@ class MainView extends Container {
|
|
31
31
|
}
|
32
32
|
|
33
33
|
MainView = Neo.setupClass(MainView);
|
34
|
-
|
34
|
+
```
|
35
35
|
|
36
36
|
</details>
|
@@ -89,13 +89,13 @@ The worst case that could happen now is that your app worker will slow down and
|
|
89
89
|
this will not affect your UI (rendering thread → main).
|
90
90
|
Probably the best solution for single page apps (SPAs) as well as multi-window apps (MWAs) looks like this:
|
91
91
|
|
92
|
-
|
92
|
+
```json neo-component
|
93
93
|
{
|
94
94
|
"cls" : "neo-worker-setup",
|
95
95
|
"tag" : "element-loader",
|
96
96
|
"vdom": {"src": "./resources/images/workers-focus.svg"}
|
97
97
|
}
|
98
|
-
|
98
|
+
```
|
99
99
|
|
100
100
|
To prevent the app worker from handling too much logic, we can optionally spawn more workers.
|
101
101
|
Each thread has its fixed scope. Let us take a quick look into each of them.
|
package/learn/benefits/Speed.md
CHANGED
@@ -20,7 +20,7 @@ Click on Preview, then use your mouse or trackpad to pan and zoom — the he
|
|
20
20
|
If you move quickly, you might reach 20,000 or 30,000 delta updates per second. We've seen some examples that go over 40,000 updates per
|
21
21
|
second — but we've never actually hit the limit.
|
22
22
|
|
23
|
-
|
23
|
+
```javascript live-preview
|
24
24
|
import Container from '../container/Base.mjs';
|
25
25
|
import Helix from '../component/Helix.mjs';
|
26
26
|
|
@@ -43,7 +43,7 @@ class MainView extends Container {
|
|
43
43
|
}
|
44
44
|
}
|
45
45
|
MainView = Neo.setupClass(MainView);
|
46
|
-
|
46
|
+
```
|
47
47
|
|
48
48
|
|
49
49
|
If you're interested, there's <a href="../../examples/component/helix/index.html" target="_blank">a more full-featured helix example</a> that includes showing delta updates,
|
@@ -3,7 +3,7 @@ Neo has a feature that allows shared, bindable, data.
|
|
3
3
|
A _state provider_ — `Neo.state.Provider` — instance holds properties that
|
4
4
|
can be bound to component properties.
|
5
5
|
|
6
|
-
|
6
|
+
```javascript live-preview
|
7
7
|
import Container from '../container/Base.mjs';
|
8
8
|
import Label from '../component/Label.mjs';
|
9
9
|
import TextField from '../form/field/Text.mjs';
|
@@ -35,7 +35,7 @@ class MainView extends Container {
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
MainView = Neo.setupClass(MainView);
|
38
|
-
|
38
|
+
```
|
39
39
|
|
40
40
|
View model properties are visible down the containment hierarchy:
|
41
41
|
Properties introduced in a parent container will be available to any child component, and properties
|
@@ -55,7 +55,7 @@ usually coded as separate classes.)
|
|
55
55
|
|
56
56
|
Below is another example.
|
57
57
|
|
58
|
-
|
58
|
+
```javascript live-preview
|
59
59
|
import Container from '../container/Base.mjs';
|
60
60
|
import Label from '../component/Label.mjs';
|
61
61
|
import Panel from '../container/Panel.mjs';
|
@@ -107,7 +107,7 @@ class MainView extends Container {
|
|
107
107
|
}
|
108
108
|
}
|
109
109
|
MainView = Neo.setupClass(MainView);
|
110
|
-
|
110
|
+
```
|
111
111
|
|
112
112
|
In this case, the main view has three child items of type `MyPanel`, each containing a label.
|
113
113
|
The main view has a state provider with a `foo` property, and the third child has its own state provider with a `foo` property.
|
@@ -17,7 +17,7 @@ Here's an example of a new component class `Simple` with three config properties
|
|
17
17
|
The `Simple` class introduces syntax. It doesn't have any content, so if you run the code you won't
|
18
18
|
see anything. We'll change that in the next example.
|
19
19
|
|
20
|
-
|
20
|
+
```javascript live-preview
|
21
21
|
import Component from '../component/Base.mjs';
|
22
22
|
import Container from '../container/Base.mjs';
|
23
23
|
|
@@ -48,7 +48,7 @@ class MainView extends Container {
|
|
48
48
|
}
|
49
49
|
}
|
50
50
|
MainView = Neo.setupClass(MainView);
|
51
|
-
|
51
|
+
```
|
52
52
|
|
53
53
|
## Detecting when a value changes
|
54
54
|
|
@@ -57,7 +57,7 @@ a _lifecyle property_. A lifecycle property provides methods that are run as the
|
|
57
57
|
updated or accessed. You're free to implment these methods to provide business rules, normalize
|
58
58
|
values, or have side-effects, such as updating a view or firing an event.
|
59
59
|
|
60
|
-
|
60
|
+
```javascript live-preview
|
61
61
|
import Component from '../component/Base.mjs';
|
62
62
|
import Container from '../container/Base.mjs';
|
63
63
|
|
@@ -98,7 +98,7 @@ class MainView extends Container {
|
|
98
98
|
}
|
99
99
|
}
|
100
100
|
MainView = Neo.setupClass(MainView);
|
101
|
-
|
101
|
+
```
|
102
102
|
|
103
103
|
This time if you run the code you'll see "hi there" in the view. That's because the Simple instance is
|
104
104
|
configured with `bar: 'hi there'`, and since that's a lifecycle property the `afterSetBar()` method
|
@@ -110,7 +110,7 @@ Typically, the _afterSet_ method is used to update a view or to fire an event.
|
|
110
110
|
|
111
111
|
Look at this code: `afterSetBar()` fires an event, and the config in the `items[]` is listening to it.
|
112
112
|
|
113
|
-
|
113
|
+
```javascript live-preview
|
114
114
|
import Component from '../component/Base.mjs';
|
115
115
|
import Container from '../container/Base.mjs';
|
116
116
|
|
@@ -149,5 +149,5 @@ class MainView extends Container {
|
|
149
149
|
}
|
150
150
|
}
|
151
151
|
MainView = Neo.setupClass(MainView);
|
152
|
-
|
152
|
+
```
|
153
153
|
|
@@ -10,7 +10,7 @@ use to describe the component you're creating> You can also access or set the pr
|
|
10
10
|
|
11
11
|
## A view with one component
|
12
12
|
|
13
|
-
|
13
|
+
```javascript live-preview
|
14
14
|
import Button from '../button/Base.mjs';
|
15
15
|
import Container from '../container/Base.mjs';
|
16
16
|
|
@@ -27,7 +27,7 @@ class MainView extends Container {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
MainView = Neo.setupClass(MainView);
|
30
|
-
|
30
|
+
```
|
31
31
|
|
32
32
|
|
33
33
|
The button config is just an object describing the button being created. In the example, it has three
|
@@ -46,7 +46,7 @@ Let's put a second button in the container.
|
|
46
46
|
|
47
47
|
## A view with two components
|
48
48
|
|
49
|
-
|
49
|
+
```javascript live-preview
|
50
50
|
import Button from '../button/Base.mjs';
|
51
51
|
import Container from '../container/Base.mjs';
|
52
52
|
|
@@ -67,7 +67,7 @@ class MainView extends Container {
|
|
67
67
|
}
|
68
68
|
|
69
69
|
MainView = Neo.setupClass(MainView);
|
70
|
-
|
70
|
+
```
|
71
71
|
|
72
72
|
If you run the example you'll see two buttons, arranged according to the `layout`. If you'd like,
|
73
73
|
modify the code to specify `ntype:'hbox'` and run it again.
|
@@ -13,7 +13,7 @@ pairs as you need.
|
|
13
13
|
The code below shows two text fields, with `listeners` for `change` and `focusEnter`.
|
14
14
|
(The events for any component are documented in the API docs.)
|
15
15
|
|
16
|
-
|
16
|
+
```javascript live-preview
|
17
17
|
import Container from '../container/Base.mjs';
|
18
18
|
import TextField from '../form/field/Text.mjs';
|
19
19
|
|
@@ -38,7 +38,7 @@ class MainView extends Container {
|
|
38
38
|
}
|
39
39
|
}
|
40
40
|
MainView = Neo.setupClass(MainView);
|
41
|
-
|
41
|
+
```
|
42
42
|
|
43
43
|
If you run the example, and open the browser's debugger, you'll see the console being logged as you type or give
|
44
44
|
focus to either field.
|
@@ -52,7 +52,7 @@ that with a _component controller_.
|
|
52
52
|
A `Neo.controller.Component` is a simple class associated with a component class. As a view is created, an
|
53
53
|
instance of its associated controller is automatically created.
|
54
54
|
|
55
|
-
|
55
|
+
```javascript live-preview
|
56
56
|
import Base from '../controller/Component.mjs';
|
57
57
|
|
58
58
|
class MainViewController extends Base {
|
@@ -86,7 +86,7 @@ class MainView extends Container {
|
|
86
86
|
}
|
87
87
|
}
|
88
88
|
MainView = Neo.setupClass(MainView);
|
89
|
-
|
89
|
+
```
|
90
90
|
|
91
91
|
|
92
92
|
|
@@ -116,7 +116,7 @@ automatically get lifecycle methods run before the value is assigned, after the
|
|
116
116
|
before the value is accessed. We're using the _after_ method to fire a `change` event.
|
117
117
|
|
118
118
|
|
119
|
-
|
119
|
+
```javascript live-preview
|
120
120
|
import Button from '../button/Base.mjs';
|
121
121
|
import Container from '../container/Base.mjs';
|
122
122
|
|
@@ -154,4 +154,4 @@ class MainView extends Container {
|
|
154
154
|
}
|
155
155
|
}
|
156
156
|
MainView = Neo.setupClass(MainView);
|
157
|
-
|
157
|
+
```
|
@@ -5,7 +5,7 @@ to test.
|
|
5
5
|
|
6
6
|
Consider this code. It's a panel with a header and a table. The table has a store.
|
7
7
|
|
8
|
-
|
8
|
+
```javascript live-preview
|
9
9
|
import Button from '../button/Base.mjs';
|
10
10
|
import Panel from '../container/Panel.mjs';
|
11
11
|
import Table from '../table/Container.mjs';
|
@@ -42,13 +42,13 @@ class MainView extends Panel {
|
|
42
42
|
}
|
43
43
|
|
44
44
|
MainView = Neo.setupClass(MainView);
|
45
|
-
|
45
|
+
```
|
46
46
|
|
47
47
|
If you wanted, any of the configs can be refactored into their own class. Here, the button, store, and table
|
48
48
|
have been refactored into their own classes, and the main view is using them. The main view is simpler and
|
49
49
|
more abstract, and each class can be reused, tested, and maintained independently.
|
50
50
|
|
51
|
-
|
51
|
+
```javascript live-preview
|
52
52
|
import Button from '../button/Base.mjs';
|
53
53
|
import Panel from '../container/Panel.mjs';
|
54
54
|
import Store from '../data/Store.mjs';
|
@@ -103,7 +103,7 @@ class MainView extends Panel {
|
|
103
103
|
}
|
104
104
|
}
|
105
105
|
MainView = Neo.setupClass(MainView);
|
106
|
-
|
106
|
+
```
|
107
107
|
|
108
108
|
There are several use-cases for creating your own classes:
|
109
109
|
|
@@ -10,7 +10,7 @@ There are two common ways of doing that:
|
|
10
10
|
Here's an example with one button. Clicking on the button will disable it.
|
11
11
|
As you can see, the handler uses the component reference pass in via `data.component`.
|
12
12
|
|
13
|
-
|
13
|
+
```javascript live-preview
|
14
14
|
import Button from '../button/Base.mjs';
|
15
15
|
import Container from '../container/Base.mjs';
|
16
16
|
import Controller from '../controller/Component.mjs';
|
@@ -39,7 +39,7 @@ class MainView extends Container {
|
|
39
39
|
}
|
40
40
|
}
|
41
41
|
MainView = Neo.setupClass(MainView);
|
42
|
-
|
42
|
+
```
|
43
43
|
|
44
44
|
## Using getReference()
|
45
45
|
|
@@ -47,7 +47,7 @@ But what if we need to get a reference to another component in the view? In that
|
|
47
47
|
you tag the component you need with a `reference` config, then use `getReference()` in
|
48
48
|
the controller.
|
49
49
|
|
50
|
-
|
50
|
+
```javascript live-preview
|
51
51
|
import Button from '../button/Base.mjs';
|
52
52
|
import Container from '../container/Base.mjs';
|
53
53
|
import Controller from '../controller/Component.mjs';
|
@@ -84,7 +84,7 @@ class MainView extends Container {
|
|
84
84
|
}
|
85
85
|
}
|
86
86
|
MainView = Neo.setupClass(MainView);
|
87
|
-
|
87
|
+
```
|
88
88
|
|
89
89
|
## Getting a reference when debugging
|
90
90
|
|
@@ -102,7 +102,7 @@ But app logic should never use `Neo.findFirst()` and very rarely use `up()` or `
|
|
102
102
|
The following example gets a reference to the _Learn_ button at the top of this site, and changes its `text`.
|
103
103
|
Again — that use of `Neo.findFirst()` might be handy when debugging, but it should never be used in app logic.
|
104
104
|
|
105
|
-
|
105
|
+
```javascript live-preview
|
106
106
|
import Button from '../button/Base.mjs';
|
107
107
|
import Container from '../container/Base.mjs';
|
108
108
|
|
@@ -128,4 +128,4 @@ class MainView extends Container {
|
|
128
128
|
}
|
129
129
|
}
|
130
130
|
MainView = Neo.setupClass(MainView);
|
131
|
-
|
131
|
+
```
|
@@ -40,7 +40,7 @@ as well as create new views classes, their controllers, and other application lo
|
|
40
40
|
|
41
41
|
Now let's look at a source file. This is the contents of `MainView.mjs`.
|
42
42
|
|
43
|
-
|
43
|
+
```javascript readonly
|
44
44
|
import Container from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
45
45
|
import Controller from './MainViewController.mjs';
|
46
46
|
import ViewModel from './MainViewModel.mjs';
|
@@ -58,7 +58,7 @@ class MainView extends Container {
|
|
58
58
|
Neo.setupClass(MainView);
|
59
59
|
|
60
60
|
export default MainView;
|
61
|
-
|
61
|
+
```
|
62
62
|
|
63
63
|
Neo.mjs views are composed of components. A component can be a "container", which means it
|
64
64
|
visually holds or groups other components, or a regular component, like a button. The main
|
@@ -78,7 +78,7 @@ you see how a component is configured let's put a button in the container.
|
|
78
78
|
First, we need to import the class that defines buttons. Then we'll describe the new button in the
|
79
79
|
`items:[].`
|
80
80
|
|
81
|
-
|
81
|
+
```javascript readonly
|
82
82
|
import Button from '../../../node_modules/neo.mjs/src/button/Base.mjs';
|
83
83
|
import Container from '../../../node_modules/neo.mjs/src/container/Base.mjs';
|
84
84
|
import Controller from './MainViewController.mjs';
|
@@ -100,7 +100,7 @@ class MainView extends Container {
|
|
100
100
|
Neo.setupClass(MainView);
|
101
101
|
|
102
102
|
export default MainView;
|
103
|
-
|
103
|
+
```
|
104
104
|
|
105
105
|
|
106
106
|
Note the entry in `items:[]`. That's a description of the button that will be the single item in our
|
@@ -120,7 +120,7 @@ Here's a simplified running example. The `model` and `controller` are omitted, b
|
|
120
120
|
actually used in the example, and the import root path is different to reflect the location of the
|
121
121
|
Neo.mjs library relative to the examples.
|
122
122
|
|
123
|
-
|
123
|
+
```javascript live-preview
|
124
124
|
import Button from '../button/Base.mjs';
|
125
125
|
import Container from '../container/Base.mjs';
|
126
126
|
|
@@ -136,5 +136,5 @@ class MainView extends Container {
|
|
136
136
|
}
|
137
137
|
|
138
138
|
MainView = Neo.setupClass(MainView);
|
139
|
-
|
139
|
+
```
|
140
140
|
|