You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: docs/components.md
+71-71
Original file line number
Diff line number
Diff line change
@@ -41,7 +41,7 @@ Here, we've defined a class called `Contact`. A contact has an id, a name and an
41
41
One way of organizing components is to use component parameter lists to send data downstream, and to define events to bubble data back upstream to a centralized module who is responsible for interfacing with the model layer.
42
42
43
43
```javascript
44
-
var ContactsWidget =m.component({
44
+
var ContactsWidget = {
45
45
controller:functionupdate() {
46
46
this.contacts=Contact.list()
47
47
this.save=function(contact) {
@@ -50,13 +50,13 @@ var ContactsWidget = m.component({
In the example above, there are 3 components. `ContactsWidget` is the top level module being rendered to `document.body`, and it is the module that has the responsibility of talking to our Model entity `Contact`, which we defined earlier.
@@ -123,7 +123,7 @@ Another way of organizing code is to distribute concrete responsibilities across
123
123
Here's a refactored version of the sample app above to illustrate:
124
124
125
125
```javascript
126
-
var ContactForm =m.component({
126
+
var ContactForm = {
127
127
controller:function() {
128
128
this.contact=m.prop(newContact())
129
129
this.save=function(contact) {
@@ -143,7 +143,7 @@ var ContactForm = m.component({
@@ -246,9 +246,9 @@ var ContactList = m.component({
246
246
})
247
247
])
248
248
}
249
-
})
249
+
}
250
250
251
-
m.module(document.body, ContactsWidget())
251
+
m.module(document.body, ContactsWidget)
252
252
```
253
253
254
254
In this iteration, both the `ContactForm` and `ContactList` components are now children of the `ContactsWidget` component and they appear simultaneously on the same page.
@@ -311,19 +311,19 @@ It's of course possible to use both aggregation of responsibility and the observ
311
311
The example below shows a variation of the contacts app where `ContactForm` is responsible for saving.
@@ -427,9 +427,9 @@ var ContactList = m.component({
427
427
})
428
428
])
429
429
}
430
-
})
430
+
}
431
431
432
-
m.mount(document.body, ContactsWidget())
432
+
m.mount(document.body, ContactsWidget)
433
433
```
434
434
435
435
Here we've moved `Contact.save(contact).then(Observable.broadcast("updateContact"))` out of the `ContactForm` component and into the model layer. In its place, `ContactForm` merely emits an action, which is then handled by this model layer observer.
@@ -445,7 +445,35 @@ Here's an example of a not-so-trivial component: a drag-n-drop file uploader. In
445
445
These two functions are here to illustrate the ability to expose APIs to component consumers that complement the component's user interface. By bundling model methods in the component, we avoid hard-coding how files are handled once they're dropped in, and instead, we provide a useful library of functions that can be consumed flexibly to meet the demands on an application.
446
446
447
447
```javascript
448
-
var Uploader =m.component({
448
+
var Uploader = {
449
+
upload:function(options) {
450
+
var formData =newFormData
451
+
for (var key inoptions.data) {
452
+
for (var i =0; i <options.data[key].length; i++) {
453
+
formData.append(key, files[i])
454
+
}
455
+
}
456
+
457
+
//simply pass the FormData object intact to the underlying XMLHttpRequest, instead of JSON.stringify'ing it
458
+
options.serialize=function(value) {return value}
459
+
options.data= formData
460
+
461
+
returnm.request(options)
462
+
},
463
+
serialize:function(files) {
464
+
var promises =Array.prototype.slice.call(files).map(function(file) {
0 commit comments