Source: component.js

  1. /**
  2. * Copyright (c) 2015 NAVER Corp.
  3. * egjs projects are licensed under the MIT license
  4. */
  5. eg.module("component", [eg], function(ns) {
  6. "use strict";
  7. /**
  8. * A class used to manage events and options in a component
  9. * @class
  10. * @group egjs
  11. * @name eg.Component
  12. * @ko 컴포넌트의 이벤트와 옵션을 관리할 수 있게 하는 클래스
  13. *
  14. * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"}
  15. */
  16. ns.Component = ns.Class({
  17. construct: function() {
  18. // The reference count does not support yet.
  19. // this.constructor.$count = (this.constructor.$count || 0) + 1;
  20. this.eventHandler = {};
  21. this.options = {};
  22. },
  23. /**
  24. * Sets options in a component or returns them.
  25. * @ko 컴포넌트에 옵션을 설정하거나 옵션을 반환한다
  26. * @method eg.Component#option
  27. * @param {String} key The key of the option<ko>옵션의 키</ko>
  28. * @param {Object} [value] The option value that corresponds to a given key <ko>키에 해당하는 옵션값</ko>
  29. * @return {eg.Component|Object} An instance, an option value, or an option object of a component itself.<br>- If both key and value are used to set an option, it returns an instance of a component itself.<br>- If only a key is specified for the parameter, it returns the option value corresponding to a given key.<br>- If nothing is specified, it returns an option object. <ko>컴포넌트 자신의 인스턴스나 옵션값, 옵션 객체.<br>- 키와 값으로 옵션을 설정하면 컴포넌트 자신의 인스턴스를 반환한다.<br>- 파라미터에 키만 설정하면 키에 해당하는 옵션값을 반환한다.<br>- 파라미터에 아무것도 설정하지 않으면 옵션 객체를 반환한다.</ko>
  30. * @example
  31. var Some = eg.Class.extend(eg.Component, {
  32. construct: function(options){
  33. this.options = options; // You have to set this.options.
  34. }
  35. });
  36. var some = new Some({
  37. "foo": 1,
  38. "bar": 2,
  39. });
  40. some.option("foo"); // return 1
  41. some.option("foo",3); // return some instance
  42. some.option(); // return options object.
  43. some.option({
  44. "foo" : 10,
  45. "bar" : 20,
  46. "baz" : 30
  47. }); // return some instance.
  48. */
  49. option: function(key, value) {
  50. if (arguments.length >= 2) {
  51. this.options[key] = value;
  52. return this;
  53. }
  54. if (typeof key === "string") {
  55. return this.options[key];
  56. }
  57. if (arguments.length === 0) {
  58. return this.options;
  59. }
  60. for (var i in key) {
  61. this.options[i] = key[i];
  62. }
  63. return this;
  64. },
  65. /**
  66. * Triggers a custom event.
  67. * @ko 커스텀 이벤트를 발생시킨다
  68. * @method eg.Component#trigger
  69. * @param {String} eventName The name of the custom event to be triggered <ko>발생할 커스텀 이벤트의 이름</ko>
  70. * @param {Object} customEvent Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko>
  71. * @return {Boolean} Indicates whether the event has occurred. If the stop() method is called by a custom event handler, it will return false and prevent the event from occurring. <ko>이벤트 발생 여부. 커스텀 이벤트 핸들러에서 stop() 메서드를 호출하면 'false'를 반환하고 이벤트 발생을 중단한다.</ko>
  72. * @example
  73. var Some = eg.Class.extend(eg.Component,{
  74. "some": function(){
  75. this.trigger("hi");// fire hi event.
  76. }
  77. });
  78. */
  79. trigger: function(eventName, customEvent) {
  80. customEvent = customEvent || {};
  81. var handlerList = this.eventHandler[eventName] || [];
  82. var hasHandlerList = handlerList.length > 0;
  83. if (!hasHandlerList) {
  84. return true;
  85. }
  86. // If detach method call in handler in first time then handeler list calls.
  87. handlerList = handlerList.concat();
  88. customEvent.eventType = eventName;
  89. var isCanceled = false;
  90. var arg = [customEvent];
  91. var i;
  92. var len;
  93. var handler;
  94. customEvent.stop = function() {
  95. isCanceled = true;
  96. };
  97. if ((len = arguments.length) > 2) {
  98. arg = arg.concat(Array.prototype.slice.call(arguments, 2, len));
  99. }
  100. for (i = 0; handler = handlerList[i]; i++) {
  101. handler.apply(this, arg);
  102. }
  103. return !isCanceled;
  104. },
  105. /**
  106. * Executed event just one time.
  107. * @ko 이벤트가 한번만 실행된다.
  108. * @method eg.Component#once
  109. * @param {eventName} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
  110. * @param {Function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
  111. * @return {eg.Component} An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
  112. * @example
  113. var Some = eg.Class.extend(eg.Component,{
  114. "hi": function(){
  115. alert("hi");
  116. },
  117. "thing": function(){
  118. this.once("hi",this.hi);
  119. }
  120. });
  121. var some = new Some();
  122. some.thing();
  123. some.trigger("hi");
  124. // fire alert("hi");
  125. some.trigger("hi");
  126. // Nothing happens
  127. */
  128. once: function(eventName, handlerToAttach) {
  129. if (typeof eventName === "object" &&
  130. typeof handlerToAttach === "undefined") {
  131. var eventHash = eventName;
  132. var i;
  133. for (i in eventHash) {
  134. this.once(i, eventHash[i]);
  135. }
  136. return this;
  137. } else if (typeof eventName === "string" &&
  138. typeof handlerToAttach === "function") {
  139. var self = this;
  140. this.on(eventName, function listener() {
  141. var arg = Array.prototype.slice.call(arguments);
  142. handlerToAttach.apply(self, arg);
  143. self.off(eventName, listener);
  144. });
  145. }
  146. return this;
  147. },
  148. /**
  149. * Checks whether an event has been attached to a component.
  150. * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다.
  151. * @method eg.Component#hasOn
  152. * @param {String} eventName The name of the event to be attached <ko>등록 여부를 확인할 이벤트의 이름</ko>
  153. * @return {Boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko>
  154. * @example
  155. var Some = eg.Class.extend(eg.Component,{
  156. "some": function(){
  157. this.hasOn("hi");// check hi event.
  158. }
  159. });
  160. */
  161. hasOn: function(eventName) {
  162. return !!this.eventHandler[eventName];
  163. },
  164. /**
  165. * Attaches an event to a component.
  166. * @ko 컴포넌트에 이벤트를 등록한다.
  167. * @method eg.Component#on
  168. * @param {eventName} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
  169. * @param {Function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
  170. * @return {eg.Component} An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
  171. * @example
  172. var Some = eg.Class.extend(eg.Component,{
  173. "hi": function(){},
  174. "some": function(){
  175. this.on("hi",this.hi); //attach event
  176. }
  177. });
  178. */
  179. on: function(eventName, handlerToAttach) {
  180. if (typeof eventName === "object" &&
  181. typeof handlerToAttach === "undefined") {
  182. var eventHash = eventName;
  183. var i;
  184. for (i in eventHash) {
  185. this.on(i, eventHash[i]);
  186. }
  187. return this;
  188. } else if (typeof eventName === "string" &&
  189. typeof handlerToAttach === "function") {
  190. var handlerList = this.eventHandler[eventName];
  191. if (typeof handlerList === "undefined") {
  192. handlerList = this.eventHandler[eventName] = [];
  193. }
  194. handlerList.push(handlerToAttach);
  195. }
  196. return this;
  197. },
  198. /**
  199. * Detaches an event from the component.
  200. * @ko 컴포넌트에 등록된 이벤트를 해제한다
  201. * @method eg.Component#off
  202. * @param {eventName} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko>
  203. * @param {Function} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko>
  204. * @return {eg.Component} An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko>
  205. * @example
  206. var Some = eg.Class.extend(eg.Component,{
  207. "hi": function(){},
  208. "some": function(){
  209. this.off("hi",this.hi); //detach event
  210. }
  211. });
  212. */
  213. off: function(eventName, handlerToDetach) {
  214. // All event detach.
  215. if (arguments.length === 0) {
  216. this.eventHandler = {};
  217. return this;
  218. }
  219. // All handler of specific event detach.
  220. if (typeof handlerToDetach === "undefined") {
  221. if (typeof eventName === "string") {
  222. this.eventHandler[eventName] = undefined;
  223. return this;
  224. } else {
  225. var eventHash = eventName;
  226. for (var i in eventHash) {
  227. this.off(i, eventHash[i]);
  228. }
  229. return this;
  230. }
  231. }
  232. // The handler of specific event detach.
  233. var handlerList = this.eventHandler[eventName];
  234. if (handlerList) {
  235. var k;
  236. var handlerFunction;
  237. for (k = 0; handlerFunction = handlerList[k]; k++) {
  238. if (handlerFunction === handlerToDetach) {
  239. handlerList.splice(k, 1);
  240. break;
  241. }
  242. }
  243. }
  244. return this;
  245. }
  246. });
  247. });
comments powered by Disqus