views:

70

answers:

3

I'm not entirely sure how to implement OOP concepts in JS.

I have a class which is entirely declared in its constructor:

function AjaxList(settings)
{

    // all these vars are of dubious necessity... could probably just use `settings` directly
    var _jq_choice_selector = settings['choice_selector'];
    var _jq_chosen_list = settings['chosen_list'];
    var _cb_onRefresh = settings['on_refresh'];
    var _url_all_choices = settings['url_choices'];
    var _url_chosen = settings['url_chosen'];
    var _url_delete_format = settings['url_delete_format'];

    var jq_choice_selector_form = _jq_choice_selector.closest("form");
    if (DEBUG && jq_choice_selector_form.length != 1)
    {
        throw("There was an error selecting the form for the choice selector.");
    }

    function refresh()
    {
        _updateChoicesSelector();
        _updateChosenList();
        _cb_onRefresh();
    };

    AjaxList.prototype.refresh = refresh; // will this be called on all AjaxLists, or just the instance used to call it?
    // AjaxList.refresh = refresh; // will this be called on all AjaxLists, or just the instance used to call it?

    // ...
}

There are multiple instances of AjaxList. When I call refresh() on one of them, I want only that one list to refresh itself. In the following instance:

term_list = AjaxList(settings);
term_list.refresh();

The refresh() call seems to make all the AjaxLists refresh themselves. What is the correct way to do this?

I'm using jQuery, if it makes any difference.

+2  A: 

You should not redefine the prototype function in the constructor. If you want to create a privileged function use this.methodname = ... from the constructor.

function AjaxList() {
  var privateVar = 0;
  function privateFunction() {
    //...
  }
  //create a refresh function just for this instance of the AjaxList
  this.refresh = function() {
    //privileged function, it can access the 'privateVar & privateFunction'
    privateVar++;
  }
}
//public functions that don't need access to the private variables/functions
AjaxList.prototype.publicFunction=function() {

};

Also if you want to create a proper object, you need to change

term_list = AjaxList(settings);

to

term_list = new AjaxList(settings);
nxt
+2  A: 
AjaxList = function(settings) {
    this._jq_choice_selector = settings["choice_selector"];
    this._jq_chosen_list = settings["chosen_list"];
    this._cb_onRefresh = settings["on_refresh"];
    this._url_all_choices = settings["url_choices"];
    this._url_chosen = settings["url_chosen"];
    this._url_delete_format = settings["url_delete_format"];

    this.jq_choice_selector_form = _jq_choice_selector.closest("form");
    if (DEBUG && jq_choice_selector_form.length != 1) {
        throw "There was an error selecting the form for the choice selector.";
    }
};

AjaxList.prototype = {
    _updateChoicesSelector: function() { },
    _updateChosenList: function() { },
    _cb_onRefresh: function() { },

    refresh: function() {
        this._updateChoicesSelector();
        this._updateChosenList();
        this._cb_onRefresh();
    }
};

Given that structure, you should be able to call:

var ajaxList = new AjaxList(settings);
ajaxList.refresh(); // etc.
Matthew Abbott
+1  A: 

I'm using jQuery, if it makes any difference.

No it doesn't. See my answer here: What's the difference between Javascript, Jquery and Ajax?

I have a class which is entirely declared in its constructor

There are no classes in Javascript. Forget them. You really need to learn some of the basics of this language in order to use them. It's not Java, even though it looks similar.

If you have a Constructor Function it will create an instance. The shared methods will be in the prototype chain, and only instance specific data goes right into the function with the this keyword.

So the basic concept of an object would look like this:

// constructor of an instance
function MyObject( param1, param2 ) {
  this.param1 = param1;
  this.param2 = param2;
  this.param3 = 32;
  return this; // [optional]
}

// Public methods can be called by any instance.
// Instances share their prototype object.
// The this keyword always points to the current
// instance that calls the method.
MyObject.prototype.sum = function() {
  return this.param1 + this.param2 + this.param3;
}

// refresh should be a shared method, since it
// does the same thing on every instance
MyObject.prototype.refresh = function() {
  // do the refresh
  // ...
}

The power of this concept is that there is only one refresh function in memory. And it can deal with any instance. In addition, if another object inherits from MyObject the refresh function will be inherited. But in the memory there will be still one shared refresh function. And it can deal with any of the parent or child instances.

galambalazs