lundi 29 août 2016

Correct structure for "static" type objects in Javascript

I'm struggling to get to grips with creating "static" object types in JavaScript (I doubt I've even worded that correctly...).

In the following code, I'm trying to create a jQuery plugin (I suspect that is irrelevant, though), which creates multiple CrmQuery each with their own contextual information passed in as instance. I also want to create a "static" object for all the CrmQuery to use (it can be stateless), and was hoping to contain it within the CrmQuery namespace.

This is the structure I have, but when calling CrmQuery.searchOperator[instance.Operator].buildCondition(instance.fieldName, searchTerm), the buildCondition function doesn't have access to the oDataOperator function in CrmQuery.searchOperator. I've tried referencing it in many ways, not just searchOperator.oDataOperator, and this is a reference to the actual property, not CrmQuery.searchOperator.

Structure:

(function($) { 
...
var crmQuery = new CrmQuery(instance);
var data = crmQuery.searchCrm(searchTerm);
... 

var CrmQuery = function(instance) {
    ...
    this.oDataUrl = function() {
        ...
        oDataFilter += CrmQuery.searchOperator[instance.Operator].buildCondition(instance.fieldName, searchTerm);
        ...
        return oDataFilter;
    }();

    this.searchCrm(searchTerm) {
        ...
        url += this.oDataUrl;
    }
    ...
}

CrmQuery.searchOperator = {
    oDataFunctionOperator: function oDataFunctionOperator(fieldName, searchTerm, operator) {
        return operator + "(" + fieldName + ", '" + searchTerm + "')";
    },
    oDataOperator: function oDataOperator(fieldName, searchTerm, operator) {
        return fieldName + " " + operator + " '" + searchTerm +"'";
    },
    STARTSWITH: { 
        operator: "startswith", 
        buildCondition: function(fieldName, searchTerm) { 
                return this.oDataFunctionOperator(fieldName, searchTerm, this.operator) 
            }
    },
    ENDSWITH: { 
        operator: "endswith", 
        buildCondition: function(fieldName, searchTerm) { 
                return searchOperator.oDataFunctionOperator(fieldName, searchTerm, this.operator) 
            }
    },
    CONTAINS: { 
        operator: "substringof", 
        buildCondition: function(fieldName, searchTerm) { 
                return searchOperator.oDataFunctionOperator(fieldName, searchTerm, this.operator) 
            }
    },
    EXACTMATCH: { 
        operator: "eq", 
        buildCondition: function(fieldName, searchTerm) { 
                return searchOperator.oDataOperator(fieldName, searchTerm, this.operator) 
            }
    },
    toString: function () {
        var thisVar = this;
        var output = "searchOperator enum. ";
        output += $.map(Object.keys(this), function (i) {
            if (typeof thisVar[i] !== "function") 
                return i + ": " + thisVar[i].operator;
        }).join(", ");
        return output;
    }
}
...
}(jQuery));

What is the correct way to implement a pattern like this in JavaScript?

I hope this makes sense? Apologies if it's too verbose, but I didn't want to leave anything out that may be important.

Many thanks, James

Aucun commentaire:

Enregistrer un commentaire