Browse Source

trapIter:tag:do:

Herbert Vojčík 12 years ago
parent
commit
c89249d621
7 changed files with 85 additions and 8 deletions
  1. 3 3
      README.md
  2. 10 1
      js/Trapped-Demo.deploy.js
  3. 12 3
      js/Trapped-Demo.js
  4. 20 0
      js/Trapped-Frontend.deploy.js
  5. 25 0
      js/Trapped-Frontend.js
  6. 6 1
      st/Trapped-Demo.st
  7. 9 0
      st/Trapped-Frontend.st

+ 3 - 3
README.md

@@ -15,11 +15,11 @@ You _can_ try it, though it still misses a lot.
 
 What is working:
  - viewmodel -> view update propagation
- - showing simple data in view.
+ - showing simple data in view
+ - iterations in view.
 
 What is missing:
  - optimizations ;-)
- - iterations in view
  - view -> viewmodel change propagation
 
 How can I try it?
@@ -41,7 +41,7 @@ The `App` instance is put into global `AppVM` variable in `demo.html` initializa
 Trapped is pretty light: the view model wraps any object (via `payload:`,
 as seen in `App >> initialize`). The view is subclass of plain `Widget`, but inside it,
 uses of `trapShow:` (which itself uses `trap:read:`), `trap:toggle:` and `trapDescend:` allows you
-to bind data from view model.
+to bind data from view model. You can also iterate arrays in the model using `trapIter:tag:do:`.
 
 To see viewmodel->view update working, try
 

+ 10 - 1
js/Trapped-Demo.deploy.js

@@ -6,13 +6,22 @@ smalltalk.method({
 selector: "renderOn:",
 fn: function (html){
 var self=this;
+var $1,$2;
 smalltalk.send(smalltalk.send(html,"_h2",[]),"_trapShow_",[["title"]]);
 smalltalk.send(smalltalk.send(html,"_div",[]),"_trap_toggle_ifNotPresent_",[["items"],(function(){
 smalltalk.send(smalltalk.send(html,"_p",[]),"_with_",[(function(){
 smalltalk.send(smalltalk.send(html,"_span",[]),"_trapShow_",[[smalltalk.symbolFor("size")]]);
 return smalltalk.send(html,"_with_",[" item(s)."]);
 })]);
-return smalltalk.send(smalltalk.send(html,"_p",[]),"_trapShow_",[[]]);
+return smalltalk.send(smalltalk.send(html,"_form",[]),"_with_",[(function(){
+return smalltalk.send(smalltalk.send(html,"_ul",[]),"_trapIter_tag_do_",[[],smalltalk.symbolFor("li"),(function(each){
+$1=smalltalk.send(html,"_input",[]);
+smalltalk.send($1,"_type_",["checkbox"]);
+$2=smalltalk.send($1,"_at_put_",["checked",true]);
+$2;
+return smalltalk.send(html,"_with_",[each]);
+})]);
+})]);
 }),(function(){
 return smalltalk.send(html,"_with_",["Loading ..."]);
 })]);

+ 12 - 3
js/Trapped-Demo.js

@@ -7,20 +7,29 @@ selector: "renderOn:",
 category: 'rendering',
 fn: function (html){
 var self=this;
+var $1,$2;
 smalltalk.send(smalltalk.send(html,"_h2",[]),"_trapShow_",[["title"]]);
 smalltalk.send(smalltalk.send(html,"_div",[]),"_trap_toggle_ifNotPresent_",[["items"],(function(){
 smalltalk.send(smalltalk.send(html,"_p",[]),"_with_",[(function(){
 smalltalk.send(smalltalk.send(html,"_span",[]),"_trapShow_",[[smalltalk.symbolFor("size")]]);
 return smalltalk.send(html,"_with_",[" item(s)."]);
 })]);
-return smalltalk.send(smalltalk.send(html,"_p",[]),"_trapShow_",[[]]);
+return smalltalk.send(smalltalk.send(html,"_form",[]),"_with_",[(function(){
+return smalltalk.send(smalltalk.send(html,"_ul",[]),"_trapIter_tag_do_",[[],smalltalk.symbolFor("li"),(function(each){
+$1=smalltalk.send(html,"_input",[]);
+smalltalk.send($1,"_type_",["checkbox"]);
+$2=smalltalk.send($1,"_at_put_",["checked",true]);
+$2;
+return smalltalk.send(html,"_with_",[each]);
+})]);
+})]);
 }),(function(){
 return smalltalk.send(html,"_with_",["Loading ..."]);
 })]);
 return self},
 args: ["html"],
-source: "renderOn: html\x0a\x09html h2 trapShow: #('title').\x0a    html div trap: #('items') toggle: [\x0a        html p with: [ html span trapShow: #(#size). html with: ' item(s).' ].\x0a\x09\x09html p trapShow: #()\x0a    ] ifNotPresent: [ html with: 'Loading ...' ]",
-messageSends: ["trapShow:", "h2", "trap:toggle:ifNotPresent:", "with:", "span", "p", "div"],
+source: "renderOn: html\x0a\x09html h2 trapShow: #('title').\x0a    html div trap: #('items') toggle: [\x0a        html p with: [ html span trapShow: #(#size). html with: ' item(s).' ].\x0a\x09\x09html form with: [ html ul trapIter: #() tag: #li do: [ :each |\x0a            html input\x0a                type: 'checkbox';\x0a                at: 'checked' put: true.\x0a            html with: each\x0a        ]]\x0a    ] ifNotPresent: [ html with: 'Loading ...' ]",
+messageSends: ["trapShow:", "h2", "trap:toggle:ifNotPresent:", "with:", "span", "p", "trapIter:tag:do:", "type:", "input", "at:put:", "ul", "form", "div"],
 referencedClasses: []
 }),
 smalltalk.AppView);

+ 20 - 0
js/Trapped-Frontend.deploy.js

@@ -435,6 +435,26 @@ return self}
 }),
 smalltalk.TagBrush);
 
+smalltalk.addMethod(
+"_trapIter_tag_do_",
+smalltalk.method({
+selector: "trapIter:tag:do:",
+fn: function (path,aSymbol,aBlock){
+var self=this;
+smalltalk.send(self,"_trap_read_",[path,(function(model,html){
+smalltalk.send(smalltalk.send(html,"_root",[]),"_empty",[]);
+if(($receiver = model) == nil || $receiver == undefined){
+return model;
+} else {
+return smalltalk.send(model,"_withIndexDo_",[(function(item,i){
+return smalltalk.send(smalltalk.send(html,"_perform_",[aSymbol]),"_trap_read_",[[i],aBlock]);
+})]);
+};
+})]);
+return self}
+}),
+smalltalk.TagBrush);
+
 smalltalk.addMethod(
 "_trapShow_",
 smalltalk.method({

+ 25 - 0
js/Trapped-Frontend.js

@@ -572,6 +572,31 @@ referencedClasses: []
 }),
 smalltalk.TagBrush);
 
+smalltalk.addMethod(
+"_trapIter_tag_do_",
+smalltalk.method({
+selector: "trapIter:tag:do:",
+category: '*Trapped-Frontend',
+fn: function (path,aSymbol,aBlock){
+var self=this;
+smalltalk.send(self,"_trap_read_",[path,(function(model,html){
+smalltalk.send(smalltalk.send(html,"_root",[]),"_empty",[]);
+if(($receiver = model) == nil || $receiver == undefined){
+return model;
+} else {
+return smalltalk.send(model,"_withIndexDo_",[(function(item,i){
+return smalltalk.send(smalltalk.send(html,"_perform_",[aSymbol]),"_trap_read_",[[i],aBlock]);
+})]);
+};
+})]);
+return self},
+args: ["path", "aSymbol", "aBlock"],
+source: "trapIter: path tag: aSymbol do: aBlock\x0a    self trap: path read: [ :model :html |\x0a        html root empty.\x0a        model ifNotNil: [ model withIndexDo: [ :item :i |\x0a            (html perform: aSymbol) trap: {i} read: aBlock\x0a        ]]\x0a    ]",
+messageSends: ["trap:read:", "empty", "root", "ifNotNil:", "withIndexDo:", "perform:"],
+referencedClasses: []
+}),
+smalltalk.TagBrush);
+
 smalltalk.addMethod(
 "_trapShow_",
 smalltalk.method({

+ 6 - 1
st/Trapped-Demo.st

@@ -9,7 +9,12 @@ renderOn: html
 	html h2 trapShow: #('title').
     html div trap: #('items') toggle: [
         html p with: [ html span trapShow: #(#size). html with: ' item(s).' ].
-		html p trapShow: #()
+		html form with: [ html ul trapIter: #() tag: #li do: [ :each |
+            html input
+                type: 'checkbox';
+                at: 'checked' put: true.
+            html with: each
+        ]]
     ] ifNotPresent: [ html with: 'Loading ...' ]
 ! !
 

+ 9 - 0
st/Trapped-Frontend.st

@@ -214,6 +214,15 @@ trap: path toggle: aBlock ifNotPresent: anotherBlock
     ]
 !
 
+trapIter: path tag: aSymbol do: aBlock
+    self trap: path read: [ :model :html |
+        html root empty.
+        model ifNotNil: [ model withIndexDo: [ :item :i |
+            (html perform: aSymbol) trap: {i} read: aBlock
+        ]]
+    ]
+!
+
 trapShow: path
 	self trapShow: path default: []
 !