Revision 95ff92b4

b/snf-cyclades-app/synnefo/ui/static/snf/js/models.js
72 72
        api: snf.api,
73 73
        api_type: 'compute',
74 74
        has_status: false,
75
        auto_bind: [],
76

  
75 77

  
76 78
        initialize: function() {
79
            var self = this;
80
            
81
            this._proxy_model_cache = {};
82
            _.each(this.auto_bind, function(fname) {
83
              self[fname] = _.bind(self[fname], self);
84
            });
85

  
77 86
            if (this.has_status) {
78 87
                this.bind("change:status", this.handle_remove);
79 88
                this.handle_remove();
80 89
            }
81 90
            
82 91
            this.api_call = _.bind(this.api.call, this);
92
              
93
            if (this.proxy_attrs) {
94
              this.init_proxy_attrs();             
95
            }
96

  
97
            if (this.storage_attrs) {
98
              this.init_storage_attrs();
99
            }
100

  
101
            if (this.model_actions) {
102
              this.init_model_actions();             
103
            }
104

  
83 105
            models.Model.__super__.initialize.apply(this, arguments);
106

  
107
        },
108
        
109
        // Initialize model actions object
110
        // For each entry in model's model_action object register the relevant 
111
        // model proxy `can_<actionname>` attributes.
112
        init_model_actions: function() {
113
          var actions = _.keys(this.model_actions);
114
          this.set({
115
            "actions": new models._ActionsModel({}, {
116
              actions: actions,
117
              model: this
118
            })
119
          });
120
          this.actions = this.get("actions");
121

  
122
          _.each(this.model_actions, function(params, key){
123
            var attr = 'can_' + key;
124
            if (params.length == 0) { return }
125
            var deps = params[0];
126
            var cb = _.bind(params[1], this);
127
            _.each(deps, function(dep) {
128
              this._set_proxy_attr(attr, dep, cb);
129
            }, this);
130
          }, this);
84 131
        },
132
        
133
        // Initialize proxy storage model attributes. These attribues allows 
134
        // us to automatically access cross collection associated objects.
135
        init_storage_attrs: function() {
136
          _.each(this.storage_attrs, function(params, attr) {
137
            var store, key, attr_name;
138
            store = synnefo.storage[params[0]];
139
            key = params[1];
140
            attr_name = attr;
141
          
142
            var resolve_related_instance = function(storage, attr_name, val) {
143
              var data = {};
144

  
145
              if (!val) { 
146
                // update with undefined and return
147
                data[key] = undefined;
148
                this.set(data);
149
                return;
150
              };
151
            
152
              // retrieve related object (check if its a Model??)
153
              var obj = store.get(val);
154
              
155
              if (obj) {
156
                // set related object
157
                data[attr_name] = obj;
158
                this.set(data, {silent:true})
159
                this.trigger("change:" + attr_name, obj);
160
              } else {
161
                var self = this;
162
                var retry = window.setInterval(function(){
163
                  var obj = store.get(val);
164
                  if (obj) {
165
                    data[key] = obj;
166
                    self.set(data, {silent:true})
167
                    self.trigger("change:" + attr_name, obj);
168
                    clearInterval(retry);
169
                  }
170
                }, 10);
171
              }
172
            }
173

  
174
            this.bind('change:' + attr, function() {
175
              resolve_related_instance.call(this, store, key, this.get(attr))
176
            });
85 177

  
178
            this.bind('add', function() {
179
              resolve_related_instance.call(this, store, key, this.get(attr))
180
            });
181
          }, this);
182
        },
183
        
184
        _proxy_model_cache: {},
185
        
186
        _set_proxy_attr: function(attr, check_attr, cb) {
187
          // initial set
188
          var data = {};
189
          data[attr] = cb.call(this, this.get(check_attr));
190
          if (data[attr] !== undefined) {
191
            this.set(data, {silent:true});
192
          }
193
          
194
          this.bind('change:' + check_attr, function() {
195
            if (this.get(check_attr) instanceof models.Model) {
196
              var model = this.get(check_attr);
197
              var proxy_cache_key = attr + '_' + check_attr;
198
              if (this._proxy_model_cache[proxy_cache_key]) {
199
                var proxy = this._proxy_model_cache[proxy_cache_key];
200
                proxy[0].unbind('change', proxy[1]);
201
              }
202
              var changebind = _.bind(function() {
203
                var data = {};
204
                data[attr] = cb.call(this, this.get(check_attr));
205
                this.set(data);
206
              }, this);
207
              model.bind('change', changebind);
208
              this._proxy_model_cache[proxy_cache_key] = [model, changebind];
209
            }
210
            var val = cb.call(this, this.get(check_attr));
211
            var data = {};
212
            if (this.get(attr) !== val) {
213
              data[attr] = val;
214
              this.set(data);
215
            }
216
          }, this);
217
        },
218

  
219
        init_proxy_attrs: function() {
220
          _.each(this.proxy_attrs, function(opts, attr){
221
            var cb = opts[1];
222
            _.each(opts[0], function(check_attr){
223
              this._set_proxy_attr(attr, check_attr, cb)
224
            }, this);
225
          }, this);
226
        },
227
        
86 228
        handle_remove: function() {
87 229
            if (this.get("status") == 'DELETED') {
88 230
                if (this.collection) {
......
2492 2634

  
2493 2635
    })
2494 2636
    
2637
    models._ActionsModel = models.Model.extend({
2638
      defaults: { pending: null },
2639
      actions: [],
2640
      status: {
2641
        INACTIVE: 0,
2642
        PENDING: 1,
2643
        CALLED: 2
2644
      },
2645

  
2646
      initialize: function(attrs, opts) {
2647
        models._ActionsModel.__super__.initialize.call(this, attrs);
2648
        this.actions = opts.actions;
2649
        this.model = opts.model;
2650
        this.bind("change", function() {
2651
          this.set({'pending': this.get_pending()});
2652
        }, this);
2653
        this.clear();
2654
      },
2655
      
2656
      _in_status: function(st) {
2657
        var actions = null;
2658
        _.each(this.attributes, function(status, action){
2659
          if (status == st) {
2660
            if (!actions) {
2661
              actions = []
2662
            }
2663
            actions.push(action);
2664
          }
2665
        });
2666
        return actions;
2667
      },
2668

  
2669
      get_pending: function() {
2670
        return this._in_status(this.status.PENDING);
2671
      },
2672

  
2673
      unset_pending_action: function(action) {
2674
        var data = {};
2675
        data[action] = this.status.INACTIVE;
2676
        this.set(data);
2677
      },
2678

  
2679
      set_pending_action: function(action, reset_pending) {
2680
        reset_pending = reset_pending === undefined ? true : reset_pending;
2681
        var data = {};
2682
        data[action] = this.status.PENDING;
2683
        if (reset_pending) {
2684
          this.reset_pending();
2685
        }
2686
        this.set(data);
2687
      },
2688
      
2689
      reset_pending: function() {
2690
        var data = {};
2691
        _.each(this.actions, function(action) {
2692
          data[action] = this.status.INACTIVE;
2693
        }, this);
2694
        this.set(data);
2695
      }
2696
    });
2697

  
2495 2698
    models.PublicPool = models.Model.extend({});
2496 2699
    models.PublicPools = models.Collection.extend({
2497 2700
      model: models.PublicPool,

Also available in: Unified diff