PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/cfzwww/static/javascript/libs/marionettejs/backbone.babysitter.js

https://bitbucket.org/uris77/cfz-www
JavaScript | 193 lines | 104 code | 37 blank | 52 comment | 13 complexity | ff486fb422103e19822ec865975ec927 MD5 | raw file
  1. // Backbone.BabySitter, v0.0.4
  2. // Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
  3. // Distributed under MIT license
  4. // http://github.com/marionettejs/backbone.babysitter
  5. // Backbone.ChildViewContainer
  6. // ---------------------------
  7. //
  8. // Provide a container to store, retrieve and
  9. // shut down child views.
  10. Backbone.ChildViewContainer = (function(Backbone, _){
  11. // Container Constructor
  12. // ---------------------
  13. var Container = function(initialViews){
  14. this._views = {};
  15. this._indexByModel = {};
  16. this._indexByCollection = {};
  17. this._indexByCustom = {};
  18. this._updateLength();
  19. this._addInitialViews(initialViews);
  20. };
  21. // Container Methods
  22. // -----------------
  23. _.extend(Container.prototype, {
  24. // Add a view to this container. Stores the view
  25. // by `cid` and makes it searchable by the model
  26. // and/or collection of the view. Optionally specify
  27. // a custom key to store an retrieve the view.
  28. add: function(view, customIndex){
  29. var viewCid = view.cid;
  30. // store the view
  31. this._views[viewCid] = view;
  32. // index it by model
  33. if (view.model){
  34. this._indexByModel[view.model.cid] = viewCid;
  35. }
  36. // index it by collection
  37. if (view.collection){
  38. this._indexByCollection[view.collection.cid] = viewCid;
  39. }
  40. // index by custom
  41. if (customIndex){
  42. this._indexByCustom[customIndex] = viewCid;
  43. }
  44. this._updateLength();
  45. },
  46. // Find a view by the model that was attached to
  47. // it. Uses the model's `cid` to find it, and
  48. // retrieves the view by it's `cid` from the result
  49. findByModel: function(model){
  50. var viewCid = this._indexByModel[model.cid];
  51. return this.findByCid(viewCid);
  52. },
  53. // Find a view by the collection that was attached to
  54. // it. Uses the collection's `cid` to find it, and
  55. // retrieves the view by it's `cid` from the result
  56. findByCollection: function(col){
  57. var viewCid = this._indexByCollection[col.cid];
  58. return this.findByCid(viewCid);
  59. },
  60. // Find a view by a custom indexer.
  61. findByCustom: function(index){
  62. var viewCid = this._indexByCustom[index];
  63. return this.findByCid(viewCid);
  64. },
  65. // Find by index. This is not guaranteed to be a
  66. // stable index.
  67. findByIndex: function(index){
  68. return _.values(this._views)[index];
  69. },
  70. // retrieve a view by it's `cid` directly
  71. findByCid: function(cid){
  72. return this._views[cid];
  73. },
  74. // Remove a view
  75. remove: function(view){
  76. var viewCid = view.cid;
  77. // delete model index
  78. if (view.model){
  79. delete this._indexByModel[view.model.cid];
  80. }
  81. // delete collection index
  82. if (view.collection){
  83. delete this._indexByCollection[view.collection.cid];
  84. }
  85. // delete custom index
  86. var cust;
  87. for (var key in this._indexByCustom){
  88. if (this._indexByCustom.hasOwnProperty(key)){
  89. if (this._indexByCustom[key] === viewCid){
  90. cust = key;
  91. break;
  92. }
  93. }
  94. }
  95. if (cust){
  96. delete this._indexByCustom[cust];
  97. }
  98. // remove the view from the container
  99. delete this._views[viewCid];
  100. // update the length
  101. this._updateLength();
  102. },
  103. // Call a method on every view in the container,
  104. // passing parameters to the call method one at a
  105. // time, like `function.call`.
  106. call: function(method, args){
  107. args = Array.prototype.slice.call(arguments, 1);
  108. this.apply(method, args);
  109. },
  110. // Apply a method on every view in the container,
  111. // passing parameters to the call method one at a
  112. // time, like `function.apply`.
  113. apply: function(method, args){
  114. var view;
  115. // fix for IE < 9
  116. args = args || [];
  117. _.each(this._views, function(view, key){
  118. if (_.isFunction(view[method])){
  119. view[method].apply(view, args);
  120. }
  121. });
  122. },
  123. // Update the `.length` attribute on this container
  124. _updateLength: function(){
  125. this.length = _.size(this._views);
  126. },
  127. // set up an initial list of views
  128. _addInitialViews: function(views){
  129. if (!views){ return; }
  130. var view, i,
  131. length = views.length;
  132. for (i=0; i<length; i++){
  133. view = views[i];
  134. this.add(view);
  135. }
  136. }
  137. });
  138. // Borrowing this code from Backbone.Collection:
  139. // http://backbonejs.org/docs/backbone.html#section-106
  140. //
  141. // Mix in methods from Underscore, for iteration, and other
  142. // collection related features.
  143. var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
  144. 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
  145. 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
  146. 'last', 'without', 'isEmpty', 'pluck'];
  147. _.each(methods, function(method) {
  148. Container.prototype[method] = function() {
  149. var views = _.values(this._views);
  150. var args = [views].concat(_.toArray(arguments));
  151. return _[method].apply(_, args);
  152. };
  153. });
  154. // return the public API
  155. return Container;
  156. })(Backbone, _);