base.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. var $ = require('jquery');
  2. var _ = require('underscore');
  3. var Backbone = require('backbone');
  4. var AppState = require('../app_state');
  5. var errorTemplate = require('./error.hbs');
  6. var BaseView = Backbone.View.extend({
  7. constructor: function(options) {
  8. // As of 1.10, Backbone no longer automatically attaches options passed
  9. // to the constructor as this.options, but that's often useful in some
  10. // cases, like a className function, that happen before initialize()
  11. // would have a chance to attach the same options.
  12. this.options = options || {};
  13. return Backbone.View.prototype.constructor.apply(this, arguments);
  14. },
  15. initialize: function() {
  16. this.subviews = [];
  17. this.rendered = false;
  18. },
  19. template: function() {},
  20. skippedRender: function() {},
  21. render: function(data) {
  22. if (this.renderOnce && this.rendered) {
  23. this.skippedRender();
  24. return this;
  25. }
  26. this.removeSubviews();
  27. var ctx = this.getRenderCtx(data);
  28. // console.log('render ctx: %o', ctx);
  29. var html = this.template(ctx);
  30. if (!this.removed) {
  31. this.$el.empty();
  32. this.$el.append(html);
  33. this.postRender(ctx);
  34. }
  35. this.rendered = true;
  36. return this;
  37. },
  38. getRenderCtx: function(data) {
  39. var ctx = {
  40. 'graph_enabled': AppState.get('GRAPH_ENABLED'),
  41. 'graph_interval': AppState.get('graph_interval'),
  42. 'graph_active': AppState.get('GRAPH_ENABLED') &&
  43. AppState.get('graph_interval') !== 'off',
  44. 'nsqlookupd': AppState.get('NSQLOOKUPD'),
  45. 'version': AppState.get('VERSION')
  46. };
  47. if (this.model) {
  48. ctx = _.extend(ctx, this.model.toJSON());
  49. } else if (this.collection) {
  50. ctx = _.extend(ctx, {'collection': this.collection.toJSON()});
  51. }
  52. if (data) {
  53. ctx = _.extend(ctx, data);
  54. }
  55. return ctx;
  56. },
  57. postRender: function() {},
  58. appendSubview: function(subview, selector) {
  59. return this.appendSubviews([subview], selector);
  60. },
  61. appendSubviews: function(subviews, selector) {
  62. this.subviews.push.apply(this.subviews, subviews);
  63. var $el = selector ? this.$(selector) : this.$el;
  64. $el.append(subviews.map(function(subview) {
  65. return subview.render().delegateEvents().el;
  66. }));
  67. },
  68. removeSubviews: function() {
  69. while (this.subviews.length) {
  70. this.subviews.pop().remove();
  71. }
  72. },
  73. remove: function() {
  74. this.removed = true;
  75. this.removeSubviews();
  76. Backbone.View.prototype.remove.apply(this, arguments);
  77. },
  78. parseErrorMessage: function(jqXHR) {
  79. var msg = 'ERROR: failed to connect to nsqadmin';
  80. if (jqXHR.readyState === 4) {
  81. try {
  82. var parsed = JSON.parse(jqXHR.responseText);
  83. msg = parsed['message'];
  84. } catch (err) {
  85. msg = 'ERROR: failed to decode JSON - ' + err.message;
  86. }
  87. }
  88. return msg;
  89. },
  90. handleAJAXError: function(jqXHR) {
  91. $('#warning, #error').hide();
  92. $('#error .alert').text(this.parseErrorMessage(jqXHR));
  93. $('#error').show();
  94. },
  95. handleViewError: function(jqXHR) {
  96. this.removeSubviews();
  97. this.$el.html(errorTemplate({'message': this.parseErrorMessage(jqXHR)}));
  98. }
  99. });
  100. module.exports = BaseView;