data.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. define("dojox/dtl/contrib/data", [
  2. "dojo/_base/kernel",
  3. "dojo/_base/lang",
  4. "../_base",
  5. "dojo/_base/array"
  6. ], function(kernel,lang,dd,array){
  7. /*=====
  8. dd = dojox.dtl;
  9. =====*/
  10. lang.getObject("dojox.dtl.contrib.data", true);
  11. var ddcd = dd.contrib.data;
  12. var first = true;
  13. ddcd._BoundItem = lang.extend(function(item, store){
  14. this.item = item;
  15. this.store = store;
  16. },
  17. {
  18. get: function(key){
  19. var store = this.store;
  20. var item = this.item;
  21. if(key == "getLabel"){
  22. return store.getLabel(item);
  23. }else if(key == "getAttributes"){
  24. return store.getAttributes(item);
  25. }else if(key == "getIdentity"){
  26. if(store.getIdentity){
  27. return store.getIdentity(item);
  28. }
  29. return "Store has no identity API";
  30. }else{
  31. if(!store.hasAttribute(item, key)){
  32. if(key.slice(-1) == "s"){
  33. if(first){
  34. first = false;
  35. kernel.deprecated("You no longer need an extra s to call getValues, it can be figured out automatically");
  36. }
  37. key = key.slice(0, -1);
  38. }
  39. if(!store.hasAttribute(item, key)){
  40. return;
  41. }
  42. }
  43. var values = store.getValues(item, key);
  44. if(!values){
  45. return;
  46. }
  47. if(!lang.isArray(values)){
  48. return new ddcd._BoundItem(values, store);
  49. }
  50. values = array.map(values, function(value){
  51. if(lang.isObject(value) && store.isItem(value)){
  52. return new ddcd._BoundItem(value, store);
  53. }
  54. return value;
  55. });
  56. values.get = ddcd._get;
  57. return values;
  58. }
  59. }
  60. });
  61. ddcd._BoundItem.prototype.get.safe = true;
  62. ddcd.BindDataNode = lang.extend(function(items, query, store, alias){
  63. this.items = items && new dd._Filter(items);
  64. this.query = query && new dd._Filter(query);
  65. this.store = new dd._Filter(store);
  66. this.alias = alias;
  67. },
  68. {
  69. render: function(context, buffer){
  70. var items = this.items && this.items.resolve(context);
  71. var query = this.query && this.query.resolve(context);
  72. var store = this.store.resolve(context);
  73. if(!store || !store.getFeatures){
  74. throw new Error("data_bind didn't receive a store");
  75. }
  76. if(query){
  77. var sync = false;
  78. store.fetch({
  79. query: query,
  80. sync: true,
  81. scope: this,
  82. onComplete: function(it){
  83. sync = true;
  84. items = it;
  85. }
  86. });
  87. if(!sync){
  88. throw new Error("The bind_data tag only works with a query if the store executed synchronously");
  89. }
  90. }
  91. var list = [];
  92. if(items){
  93. for(var i = 0, item; item = items[i]; i++){
  94. list.push(new ddcd._BoundItem(item, store));
  95. }
  96. }
  97. context[this.alias] = list;
  98. return buffer;
  99. },
  100. unrender: function(context, buffer){
  101. return buffer;
  102. },
  103. clone: function(){
  104. return this;
  105. }
  106. });
  107. lang.mixin(ddcd, {
  108. _get: function(key){
  109. if(this.length){
  110. return (this[0] instanceof ddcd._BoundItem) ? this[0].get(key) : this[0][key];
  111. }
  112. },
  113. bind_data: function(parser, token){
  114. // summary: Turns a list of data store items into DTL compatible items
  115. // example:
  116. // `contextItems` and `contextStore` should be an item list
  117. // and a data store that get assigned to `newVariable`
  118. //
  119. // | {% bind_data contextItems to contextStore as newVariable %}
  120. var parts = token.contents.split();
  121. if(parts[2] != 'to' || parts[4] != 'as' || !parts[5]){
  122. throw new Error("data_bind expects the format: 'data_bind items to store as varName'");
  123. }
  124. return new ddcd.BindDataNode(parts[1], null, parts[3], parts[5]);
  125. },
  126. bind_query: function(parser, token){
  127. // summary: Queries a data store and makes the returned items DTL compatible
  128. // example:
  129. // You can only use this with data stores that work in a synchronous
  130. // way (meaning that `onComplete` is fired during the `fetch` call).
  131. // A `sync` flag is sent to the fetch call so that stores that usually
  132. // work asynchronously make themselves syncrhonous if possible.
  133. // | {% bind_query contextQuery to contextStore as newVariable %}
  134. var parts = token.contents.split();
  135. if(parts[2] != 'to' || parts[4] != 'as' || !parts[5]){
  136. throw new Error("data_bind expects the format: 'bind_query query to store as varName'");
  137. }
  138. return new ddcd.BindDataNode(null, parts[1], parts[3], parts[5]);
  139. }
  140. });
  141. ddcd._get.safe = true;
  142. dd.register.tags("dojox.dtl.contrib", {
  143. "data": ["bind_data", "bind_query"]
  144. });
  145. return dojox.dtl.contrib.data;
  146. });