Trapped-Demo.st 4.3 KB

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