Trapped-Demo.st 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. Smalltalk current createPackage: 'Trapped-Demo'!
  2. ListKeyedIsolatedEntity subclass: #App
  3. instanceVariableNames: ''
  4. package: 'Trapped-Demo'!
  5. !App commentStamp!
  6. // Code from AngularJS Todo example, http://angularjs.org/#todo-js
  7. function TodoCtrl($scope) {
  8. $scope.todos = [
  9. {text:'learn angular', done:true},
  10. {text:'build an angular app', done:false}];
  11. $scope.addTodo = function() {
  12. $scope.todos.push({text:$scope.todoText, done:false});
  13. $scope.todoText = '';
  14. };
  15. $scope.remaining = function() {
  16. var count = 0;
  17. angular.forEach($scope.todos, function(todo) {
  18. count += todo.done ? 0 : 1;
  19. });
  20. return count;
  21. };
  22. $scope.archive = function() {
  23. var oldTodos = $scope.todos;
  24. $scope.todos = [];
  25. angular.forEach(oldTodos, function(todo) {
  26. if (!!todo.done) $scope.todos.push(todo);
  27. });
  28. };
  29. }!
  30. !App methodsFor: 'initialization'!
  31. initialize
  32. super initialize.
  33. self dispatcher: SimpleKeyedPubSub new.
  34. self model: (AppModel new title: 'Todo').
  35. self watch: #((todos) nil) do: [ self dispatcher changed: #((remaining)) ].
  36. [ self modify: #((todos)) do: [{
  37. #{'text'->'learn trapped'. 'done'->true}.
  38. #{'text'->'build a trapped app'. 'done'->false}
  39. }]] valueWithTimeout: 2000
  40. ! !
  41. Object subclass: #AppModel
  42. instanceVariableNames: 'title todos todoText'
  43. package: 'Trapped-Demo'!
  44. !AppModel commentStamp!
  45. // Code from AngularJS Todo example, http://angularjs.org/#todo-js
  46. function TodoCtrl($scope) {
  47. $scope.todos = [
  48. {text:'learn angular', done:true},
  49. {text:'build an angular app', done:false}];
  50. $scope.addTodo = function() {
  51. $scope.todos.push({text:$scope.todoText, done:false});
  52. $scope.todoText = '';
  53. };
  54. $scope.remaining = function() {
  55. var count = 0;
  56. angular.forEach($scope.todos, function(todo) {
  57. count += todo.done ? 0 : 1;
  58. });
  59. return count;
  60. };
  61. $scope.archive = function() {
  62. var oldTodos = $scope.todos;
  63. $scope.todos = [];
  64. angular.forEach(oldTodos, function(todo) {
  65. if (!!todo.done) $scope.todos.push(todo);
  66. });
  67. };
  68. }!
  69. !AppModel methodsFor: 'accessing'!
  70. remaining
  71. ^self todosNotDone size
  72. !
  73. title
  74. ^title
  75. !
  76. title: aString
  77. title := aString
  78. !
  79. todoText
  80. ^todoText
  81. !
  82. todoText: aString
  83. todoText := aString
  84. !
  85. todos
  86. ^todos
  87. !
  88. todos: anArray
  89. todos := anArray
  90. !
  91. todosNotDone
  92. ^self todos reject: [ :each | each at: 'done' ]
  93. ! !
  94. !AppModel methodsFor: 'action'!
  95. addTodo
  96. self todos add: #{'text'->self todoText. 'done'->false}.
  97. self todoText: ''
  98. !
  99. archive
  100. self todos: self todosNotDone
  101. ! !
  102. Widget subclass: #AppView
  103. instanceVariableNames: ''
  104. package: 'Trapped-Demo'!
  105. !AppView commentStamp!
  106. <!!-- Code from AngularJS Todo example, http://angularjs.org/#todo-html -->
  107. <body>
  108. <h2>Todo</h2>
  109. <div ng-controller="TodoCtrl">
  110. <span>{{remaining()}} of {{todos.length}} remaining</span>
  111. [ <a href="" ng-click="archive()">archive</a> ]
  112. <ul class="unstyled">
  113. <li ng-repeat="todo in todos">
  114. <input type="checkbox" ng-model="todo.done">
  115. <span class="done-{{todo.done}}">{{todo.text}}</span>
  116. </li>
  117. </ul>
  118. <form ng-submit="addTodo()">
  119. <input type="text" ng-model="todoText" size="30"
  120. placeholder="add new todo here">
  121. <input class="btn-primary" type="submit" value="add">
  122. </form>
  123. </div>
  124. </body>!
  125. !AppView methodsFor: 'rendering'!
  126. renderOn: html
  127. #() trapDescend: [ :snap |
  128. html h2 trap: #((title)).
  129. html div trapGuard: #((todos) (notNil)) contents: [
  130. html span trap:#((remaining)).
  131. html with: ' of '.
  132. html span trap: #((todos) (size)).
  133. html with: ' remaining [ '.
  134. html a href:''; onClick: [
  135. snap modify: [ :model | model archive ].
  136. false
  137. ]; with: 'archive'.
  138. html with: ' ]'.
  139. html ul with: [ html trapIter: #((todos)) tag: #li do: [ :each |
  140. html root empty.
  141. html input type: 'checkbox'; trap: #('done').
  142. html span trap: #('done') read: [ :model | html root class: 'done-', model ]; trap: #('text').
  143. ]].
  144. html form onSubmit: [
  145. snap modify: [ :model | model addTodo ].
  146. false
  147. ]; with: [
  148. html input type: 'text'; trap: #((todoText)); at: 'size' put: 30; placeholder: 'add new todo here'.
  149. html input class: 'btn-primary'; type: 'submit'; value: 'add'.
  150. ].
  151. ].
  152. html p trapGuard: #((todos) (isNil)) contents: 'Loading ...'.
  153. ]
  154. ! !