Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: Public methods and prototypes

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.

like image 446
Nick Heiner Avatar asked Dec 16 '22 23:12

Nick Heiner


2 Answers

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);
like image 79
nxt Avatar answered Dec 28 '22 12:12

nxt


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.
like image 26
Matthew Abbott Avatar answered Dec 28 '22 12:12

Matthew Abbott