Source: mvc/views/view.js

  1. define (
  2. ['mmirf/commonUtils','mmirf/contentElement','mmirf/storageUtils', 'require'],
  3. function(
  4. commonUtils, ContentElement, parser, require
  5. ){
  6. /**
  7. *
  8. * The View class is a kind of interface-class which gives access to the methods and data of a helper (which itself belongs to a controller)<br>
  9. * Apart from initializing some properties, the constructor also parses the view description and looks for needed helper methods.
  10. *
  11. * @class
  12. * @name View
  13. * @memberOf mmir.view
  14. * @param {Object} ctrl
  15. * Controller instance / object
  16. * @param {String} name
  17. * Name of the View
  18. * @param {String} definition
  19. * View description, i.e. the raw template code that will be processed.
  20. * May be empty: in this case the processed contents must be
  21. * added manually (cf. parser.StorageUtils)
  22. *
  23. * @requires if param definition is NOT empty: parser.RenderUtils (must be loaded beforehand via <code>require(["mmirf/renderUtils"]...</code>)
  24. * @requires if param definition is NOT empty: parser.ParseUtils (must be loaded beforehand via <code>require(["mmirf/parseUtils"]...</code>)
  25. *
  26. */
  27. function View(ctrl, name, definition){
  28. // console.log("[View] '" + name + "' loaded.");
  29. if(definition){
  30. // remove HTML comments from View
  31. definition = definition.replace(commonUtils.regexHTMLComment, '');
  32. }
  33. /**
  34. * The controller to which this view belongs.
  35. *
  36. * @type mmir.ctrl.Controller
  37. * @public
  38. * @memberOf mmir.view.View#
  39. * @member controller
  40. */
  41. this.controller = ctrl;
  42. /**
  43. * The description of the view in eHTML.
  44. *
  45. * @type String
  46. * @public
  47. * @memberOf mmir.view.View#
  48. * @member def
  49. */
  50. this.def = definition;
  51. /**
  52. * The name of the view.
  53. *
  54. * @type String
  55. * @public
  56. * @memberOf mmir.view.View#
  57. * @member name
  58. */
  59. this.name = name;
  60. /**
  61. * An array of all the views {@link mmir.view.ContentElement} objects.<br>
  62. *
  63. * @type Array<mmir.view.ContentElement>
  64. * @public
  65. * @memberOf mmir.view.View#
  66. * @member contentFors
  67. */
  68. this.contentFors = new Array();
  69. /**
  70. *
  71. * An array of all names of the for the view required helper methods.
  72. *
  73. * @deprecated helper methods must now explicitly called in template definition (using syntax <code>@helper(name,args)</code>)
  74. *
  75. * @type Array
  76. * @public
  77. * @memberOf mmir.view.View#
  78. * @member helperMethods
  79. */
  80. this.helperMethods = new Array();
  81. if(this.def){
  82. var parserUtils = typeof WEBPACK_BUILD !== 'undefined' && WEBPACK_BUILD? __webpack_require__('mmirf/parseUtils') : require('mmirf/parseUtils');
  83. var renderUtils = typeof WEBPACK_BUILD !== 'undefined' && WEBPACK_BUILD? __webpack_require__('mmirf/renderUtils') : require('mmirf/renderUtils');
  84. var parseResult = parserUtils.parse(this.def, this);
  85. for(var i=0, size = parseResult.contentFors.length; i < size ; ++i){
  86. this.contentFors.push(new ContentElement(parseResult.contentFors[i], this, parserUtils, renderUtils));
  87. }
  88. }
  89. };
  90. /**
  91. * Gets the definition of a view.
  92. *
  93. * @function getDefinition
  94. * @returns {String} The view description string
  95. * @memberOf mmir.view.View#
  96. */
  97. View.prototype.getDefinition = function(){
  98. return this.def;
  99. };
  100. /**
  101. * Gets the name of a view.
  102. *
  103. * @function getName
  104. * @returns {String} The name of the view
  105. * @memberOf mmir.view.View#
  106. */
  107. View.prototype.getName = function(){
  108. return this.name;
  109. };
  110. /**
  111. * Gets the name of a view.
  112. *
  113. * @function getController
  114. * @returns {Object} The controller for the view
  115. * @memberOf mmir.view.View#
  116. */
  117. View.prototype.getController = function(){
  118. return this.controller;
  119. };
  120. /**
  121. * Gets a specific {@link mmir.view.ContentElement} object by name.
  122. *
  123. * @function getContentElement
  124. * @param {String} name Name of the ContentElement object
  125. * @returns {object} The wanted ContentElement object or null
  126. * @memberOf mmir.view.View#
  127. */
  128. View.prototype.getContentElement = function( name){
  129. for(var i=0, size = this.contentFors.length; i < size ; ++i){
  130. if(this.contentFors[i].getName() == name){
  131. return this.contentFors[i];/////////////////////// EARLY EXIT /////////////////////////////
  132. }
  133. }
  134. return null;
  135. };
  136. /**
  137. * Gets an array of all helper methods.
  138. *
  139. * @function getHelperMethods
  140. * @returns {Array} Array of all helper methods
  141. * @memberOf mmir.view.View#
  142. */
  143. View.prototype.getHelperMethods = function(){
  144. return this.helperMethods;
  145. };
  146. /**
  147. * @function stringify
  148. * @returns {String} the stringified representation for the View
  149. * @memberOf mmir.view.View#
  150. */
  151. View.prototype.stringify = function(){
  152. // "plain properties" list
  153. var propList = [
  154. 'name',
  155. 'def'
  156. // , 'helperMethods'//DISABLE: this field is deprecated!
  157. ];
  158. //Array-properties
  159. var arrayPropList = [
  160. 'contentFors' //element type: ContentElement (stringify-able)
  161. ];
  162. //function for iterating over the property-list and generating JSON-like entries in the string-buffer
  163. var appendStringified = parser.appendStringified;
  164. var moduleNameString = '"'+this.name+this.getController().getName()+'View"';
  165. var sb = [parser.STORAGE_CODE_WRAP_PREFIX, 'require("mmirf/storageUtils").restoreObject({ classConstructor: "mmirf/view"', ','];
  166. appendStringified(this, propList, sb);
  167. //non-primitives array-properties with stringify() function:
  168. appendStringified(this, arrayPropList, sb, null, function arrayValueExtractor(name, arrayValue){
  169. var buf =['['];
  170. for(var i=0, size = arrayValue.length; i < size; ++i){
  171. buf.push(arrayValue[i].stringify());
  172. buf.push(',');
  173. }
  174. //remove last comma
  175. if(arrayValue.length > 0){
  176. buf.splice( buf.length - 1, 1);
  177. }
  178. buf.push(']');
  179. return buf.join('');
  180. });
  181. //NOTE the use of require() here, assumes that the dependency has already been loaded (i.e. has already been request by some other module!)
  182. sb.push( 'initPublish: function(){ require("mmirf/presentationManager").addView(this.getController(), this); }');
  183. sb.push(',');
  184. //TODO is there a better way to store the controller? -> by its contoller's name, and add a getter function...
  185. if(this['controller']){
  186. //getter/setter function for controller
  187. // (NOTE: this init-function needs to be called before controller can be accessed!)
  188. sb.push( 'initController: function(){');
  189. // store controller-name:
  190. sb.push( ' var ctrlName = ');
  191. sb.push( JSON.stringify(this.getController().getName()) );
  192. // ... and the getter/setter code:
  193. sb.push( '; this.controller = require("mmirf/controllerManager").get(ctrlName); },' );//TODO see remark about use of require() above
  194. //add initializer function
  195. // (NOTE: needs to be called before controller or renderer can be accessed!)
  196. sb.push( 'init: function(){');
  197. sb.push( ' this.initController(); ' );
  198. sb.push( ' }' );
  199. //NOTE: need to add comma in a separate entry
  200. // (-> in order to not break the removal method of last comma, see below)
  201. sb.push( ',' );
  202. }
  203. //if last element is a comma, remove it
  204. if(sb[sb.length - 1] === ','){
  205. sb.splice( sb.length - 1, 1);
  206. }
  207. //TODO use requirejs mechanism? (see remark above)
  208. // sb.push(' }, true); });\n require(['//<- add require-call, so that this JS-file adds itself to the loaded dependencies in requirejs
  209. // + moduleNameString + ']);');
  210. sb.push(' }, true, '+parser.STORAGE_FILE_FORMAT_NUMBER+');');
  211. sb.push(parser.STORAGE_CODE_WRAP_SUFFIX);
  212. return sb.join('');
  213. };
  214. /**
  215. * Gets an array of all helper methods.
  216. *
  217. * @deprecated helper methods must now explicitly called in template definition (using syntax <code>@helper(name,args)</code>)
  218. *
  219. * @function
  220. * @returns {Array} Array of all helper methods
  221. */
  222. View.prototype.getHelperMethods = function(){
  223. return this.helperMethods;
  224. };
  225. /**
  226. * Executes all helper methods that were specified / referenced in the view; with **data** as parameter.
  227. *
  228. * @deprecated helper methods must now explicitly called in template definition (using syntax <code>@helper(name,args)</code>)
  229. *
  230. * @function
  231. * @param {Object} data Parameter to pass to the helper methods
  232. */
  233. View.prototype.executeHelperMethods = function(data){
  234. for(var i=0, size = this.getHelperMethods().length; i < size ; ++i){
  235. this.controller.performHelper(this.getHelperMethods()[i], data);
  236. }
  237. };
  238. return View;
  239. });//END: define(..., function(){