jsondatasource.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright 2006 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Implementation of DataNode for wrapping JSON data.
  16. *
  17. */
  18. goog.provide('goog.ds.JsonDataSource');
  19. goog.require('goog.Uri');
  20. goog.require('goog.dom');
  21. goog.require('goog.dom.TagName');
  22. goog.require('goog.ds.DataManager');
  23. goog.require('goog.ds.JsDataSource');
  24. goog.require('goog.ds.LoadState');
  25. goog.require('goog.ds.logger');
  26. goog.require('goog.log');
  27. /**
  28. * Data source whose backing is a JSON-like service, in which
  29. * retreiving the resource specified by URL with the additional parameter
  30. * callback. The resource retreived is executable JavaScript that
  31. * makes a call to the named function with a JavaScript object literal
  32. * as the only parameter.
  33. *
  34. * Example URI could be:
  35. * http://www.google.com/data/search?q=monkey&callback=mycb
  36. * which might return the JS:
  37. * mycb({searchresults:
  38. * [{uri: 'http://www.monkey.com', title: 'Site About Monkeys'}]});
  39. *
  40. * TODO(user): Evaluate using goog.net.Jsonp here.
  41. *
  42. * A URI of an empty string will mean that no request is made
  43. * and the data source will be a data source with no child nodes
  44. *
  45. * @param {string|goog.Uri} uri URI for the request.
  46. * @param {string} name Name of the datasource.
  47. * @param {string=} opt_callbackParamName The parameter name that is used to
  48. * specify the callback. Defaults to 'callback'.
  49. *
  50. * @extends {goog.ds.JsDataSource}
  51. * @constructor
  52. * @final
  53. */
  54. goog.ds.JsonDataSource = function(uri, name, opt_callbackParamName) {
  55. goog.ds.JsDataSource.call(this, null, name, null);
  56. if (uri) {
  57. this.uri_ = new goog.Uri(uri);
  58. } else {
  59. this.uri_ = null;
  60. }
  61. /**
  62. * This is the callback parameter name that is added to the uri.
  63. * @type {string}
  64. * @private
  65. */
  66. this.callbackParamName_ = opt_callbackParamName || 'callback';
  67. };
  68. goog.inherits(goog.ds.JsonDataSource, goog.ds.JsDataSource);
  69. /**
  70. * Default load state is NOT_LOADED
  71. * @private
  72. */
  73. goog.ds.JsonDataSource.prototype.loadState_ = goog.ds.LoadState.NOT_LOADED;
  74. /**
  75. * Map of all data sources, needed for callbacks
  76. * Doesn't work unless dataSources is exported (not renamed)
  77. */
  78. goog.ds.JsonDataSource['dataSources'] = {};
  79. /**
  80. * Load or reload the backing data for this node.
  81. * Fires the JsonDataSource
  82. * @override
  83. */
  84. goog.ds.JsonDataSource.prototype.load = function() {
  85. if (this.uri_) {
  86. // NOTE: "dataSources" is expose above by name so that it will not be
  87. // renamed. It should therefore be accessed via array notation here so
  88. // that it also doesn't get renamed and stops the compiler from complaining
  89. goog.ds.JsonDataSource['dataSources'][this.dataName_] = this;
  90. goog.log.info(
  91. goog.ds.logger, 'Sending JS request for DataSource ' +
  92. this.getDataName() + ' to ' + this.uri_);
  93. this.loadState_ = goog.ds.LoadState.LOADING;
  94. var uriToCall = new goog.Uri(this.uri_);
  95. uriToCall.setParameterValue(
  96. this.callbackParamName_, 'JsonReceive.' + this.dataName_);
  97. goog.global['JsonReceive'][this.dataName_] =
  98. goog.bind(this.receiveData, this);
  99. var scriptEl =
  100. goog.dom.createDom(goog.dom.TagName.SCRIPT, {'src': uriToCall});
  101. goog.dom.getElementsByTagNameAndClass(goog.dom.TagName.HEAD)[0].appendChild(
  102. scriptEl);
  103. } else {
  104. this.root_ = {};
  105. this.loadState_ = goog.ds.LoadState.NOT_LOADED;
  106. }
  107. };
  108. /**
  109. * Gets the state of the backing data for this node
  110. * @return {goog.ds.LoadState} The state.
  111. * @override
  112. */
  113. goog.ds.JsonDataSource.prototype.getLoadState = function() {
  114. return this.loadState_;
  115. };
  116. /**
  117. * Receives data from a Json request
  118. * @param {Object} obj The JSON data.
  119. */
  120. goog.ds.JsonDataSource.prototype.receiveData = function(obj) {
  121. this.setRoot(obj);
  122. this.loadState_ = goog.ds.LoadState.LOADED;
  123. goog.ds.DataManager.getInstance().fireDataChange(this.getDataName());
  124. };
  125. /**
  126. * Temp variable to hold callbacks
  127. * until BUILD supports multiple externs.js files
  128. */
  129. goog.global['JsonReceive'] = {};