|
@@ -1,5 +1,21 @@
|
|
# NanoBind - Templating and Data binding on DOM in JS
|
|
# NanoBind - Templating and Data binding on DOM in JS
|
|
|
|
|
|
|
|
+## Idea
|
|
|
|
+
|
|
|
|
+### Declarative better than imperative
|
|
|
|
+
|
|
|
|
+Instead of write loops in code and/or template, just give a structure and get a view.
|
|
|
|
+
|
|
|
|
+### Clean HTML
|
|
|
|
+
|
|
|
|
+Good HTML declarative enough, to avoid using some template engine markers like `{{ varname }}`, `{% control structure syntax %}` and so on. Also, usually template loops
|
|
|
|
+requires some loopable data structure, passed into temlate engine to render.
|
|
|
|
+
|
|
|
|
+### Less better, than more
|
|
|
|
+
|
|
|
|
+It's not jQuery, Angular or Meteor. It's just a way to put and get data from DOM Tree more transparent and declarative. And **NanoBind** does nothing to conflict with
|
|
|
|
+any other framework.
|
|
|
|
+
|
|
## Requirements
|
|
## Requirements
|
|
|
|
|
|
Support of ES6 `Proxy` object.
|
|
Support of ES6 `Proxy` object.
|
|
@@ -278,3 +294,111 @@ $s.hashTable = [{ name: "Ivan",
|
|
note: "Ovulyashka",
|
|
note: "Ovulyashka",
|
|
age: "27"} ];
|
|
age: "27"} ];
|
|
```
|
|
```
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+## Getting data
|
|
|
|
+
|
|
|
|
+**NanoBind** *attaches your data to DOM HTML Element* when you set it as `nbData` property, and use it as "template" for read. But, in some cases it doesn't returns updated
|
|
|
|
+data, but other value.
|
|
|
|
+
|
|
|
|
+### Numbers
|
|
|
|
+
|
|
|
|
+Can't be returned at all, because DOM doesn't use numbers even for number properties like `value` in `li` or `value` in `input[type='number']`.
|
|
|
|
+
|
|
|
|
+### Strings
|
|
|
|
+
|
|
|
|
+Are usual result of any read for primitive values.
|
|
|
|
+
|
|
|
|
+### Boolean
|
|
|
|
+
|
|
|
|
+Returned only when `input[type='checkbox']` reading. **You can't read visibility status as `boolean`**.
|
|
|
|
+
|
|
|
|
+### Reading inputs
|
|
|
|
+
|
|
|
|
+...like `textarea`, `select`, `input` works as expected - returns what user has selected or entered into inputs.
|
|
|
|
+
|
|
|
|
+### Complex data structures like arrays and objects
|
|
|
|
+...reading recursively, as passed when set. But some collisions possible with nested inputs.
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+## Tricks
|
|
|
|
+
|
|
|
|
+### Appendable Edit
|
|
|
|
+
|
|
|
|
+simple sample of editable data set with minimal event handling
|
|
|
|
+
|
|
|
|
+```html
|
|
|
|
+<table>
|
|
|
|
+ <thead>
|
|
|
|
+ <th> age</th>
|
|
|
|
+ <th> married</th>
|
|
|
|
+ <th> surname</th>
|
|
|
|
+ <th> name</th>
|
|
|
|
+ <th> note</th>
|
|
|
|
+ </thead>
|
|
|
|
+ <tbody id="hashTable">
|
|
|
|
+ <tr>
|
|
|
|
+ <td class='age'></td>
|
|
|
|
+ <td><input type='checkbox' class='married'></td>
|
|
|
|
+ <td class='surname'></td>
|
|
|
|
+ <td class='name'></td>
|
|
|
|
+ <td><textarea class='note'></textarea></td>
|
|
|
|
+ <td><button class='btnDel'>x</button></td>
|
|
|
|
+ </tr>
|
|
|
|
+ </tbody>
|
|
|
|
+</table>
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+```javascript
|
|
|
|
+var persons = [{ name: "Ivan",
|
|
|
|
+ surname: "Ivanovv",
|
|
|
|
+ age: "57",
|
|
|
|
+ note: {value: "Buhaet", name: 'ivanovvsTextArea'},
|
|
|
|
+ married: true},
|
|
|
|
+ { name: "Petr",
|
|
|
|
+ surname: "Petroff",
|
|
|
|
+ age: "17",
|
|
|
|
+ note: "Tyolki v golove",
|
|
|
|
+ married: false,
|
|
|
|
+ },
|
|
|
|
+ { name: "Mary",
|
|
|
|
+ surname: "Tester",
|
|
|
|
+ married: true,
|
|
|
|
+ note: "Ovulyashka",
|
|
|
|
+ age: "27"} ];
|
|
|
|
+
|
|
|
|
+$s.hashTable = persons;
|
|
|
|
+
|
|
|
|
+function btnDel(){
|
|
|
|
+ var thisLine = this.parentElement.parentElement;
|
|
|
|
+ thisLine.remove();
|
|
|
|
+ $s["#hashTable tr:first-child button"] = false; //turn off first delete button
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+$s.btnDel = {onclick: btnDel};
|
|
|
|
+
|
|
|
|
+$s.addPerson = {onclick: function(){
|
|
|
|
+ var newLine = document.getElementById('hashTable').copy.children[0].cloneNode(true);
|
|
|
|
+ newLine.nbData = Object.assign({},persons[0]);
|
|
|
|
+ document.getElementById('hashTable').appendChild(newLine);
|
|
|
|
+ $s.btnDel = {onclick: btnDel};
|
|
|
|
+}}
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+Overall, I'm not sure than event handlers and other imperative things might be used this way with **NanoBind**. Maybe frameworks better for this.
|
|
|
|
+
|
|
|
|
+## TODO
|
|
|
|
+
|
|
|
|
+### Recursive HTML
|
|
|
|
+For building nested structures from same HTML subtree like tree control or menu
|
|
|
|
+
|
|
|
|
+### DOM Subtree limitation
|
|
|
|
+Now **NanoBind** works on whole DOM tree, starting from `document`. But for templating in SPA and flexibility it will be moved to any node.
|
|
|
|
+
|
|
|
|
+### Substructure `Proxy`
|
|
|
|
+Now data passed only when you're rewrite some key in `$s`. Any changes like `$s.hashTable[0].age = 19` has no effect, because object instance are same as before.
|
|
|
|
+
|
|
|
|
+### nbData collisions.
|
|
|
|
+Now every element has one or zero nbData, but any element matches on *many* selectors, potentially with many `nbData`. So, nbData should be converted to associative array
|
|
|
|
+'selector': data.
|