Pergunta

I am trying to apply objective approach in writing a very simple JS app but I cant seem to get it right...

There are several functions manipulating data in a table (in this example - highlighting rows with random colors after clicking on the link).

There is an example on JSFiddle

var MainFun = function() {}

MainFun.prototype.highlight = function(value) { 
       $(".conversationid")
          .filter(function() {
              return $(this).html() == value;
          })
          .css('background', 'transparent')
          .parent()
          .css('background', getRandomColor());
}


function getRandomColor() {
    return '#' + randHex() + "" + randHex() + "" + randHex();
}

function randHex() {
    return (Math.floor(Math.random() * 106) + 150).toString(16);
}

var f = new MainFun();

<table>
    <tr>
        <td class="message">message1</td>
        <td class="conversationid">123</td>
        <td class="details"><a href="#"onclick="f.highlight('123');">click me</a></td>             
    </tr>
    <tr>
        <td class="message">message2</td>
        <td class="conversationid">456</td>
        <td class="details"><a href="#"onclick="f.highlight('456');">click me</a></td>             
    </tr>
    <tr>
        <td class="message">message3</td>
        <td class="conversationid">123</td>
        <td class="details"><a href="#"onclick="f.highlight('123');">click me</a></td>             
    </tr>
    <tr>
        <td class="message">message4</td>
        <td class="conversationid">456</td>
        <td class="details"><a href="#"onclick="f.highlight('456');">click me</a></td>             
    </tr>

In this example, MainFun is the main objhect that should include all the functions (highlight, getRandomColor etc...)

I managed to made it work for the highlight function using prototype but when I try to do the same with the other functions, I get an error "f undefined". Could you suggest how to do it, please? Objective approach in JS seems to be quite different than in other languages... Thanks for any help!

Foi útil?

Solução

Just do it like you did it with highlight function. And call the other prototype functions (also in highlight function) with this:

MainFun.prototype.getRandomColor = function() {
    return '#' + this.randHex() + "" + this.randHex() + "" + this.randHex();
}

MainFun.prototype.randHex = function() {
    return (Math.floor(Math.random() * 106) + 150).toString(16);
}

I've updated the fiddle: jsfiddle

Note the line:

var that = this;

It's because in the jquery closure scope the meaning of this will get changed.

Outras dicas

I think this isn't a reasonable example to build a object oriented design. It's simple and should have a simple solution.

Anyway... putting each function into a super main "class" MainFun has nothing to do with an "object oriented approach". It's the same design like before. If you want to start with OOP you should think about responsibilities and create objects for them. In this example we could extract a ColorPicker from the MainFunc. And a RandomColorPicker could have a dependency to a random engine which is just a function returning a random hex.

JSFiddle

var Main = function(colorPicker) {
    var that = this;
    this.colorPicker = colorPicker;  

    this.highlight = function(value) {
        $(".conversationid").filter(function() { 
            return $(this).html() == value; 
        })
        .css('background', 'transparent')
        .parent()
        .css('background', that.colorPicker.pickColor());
    };
};

var RandomColorPicker = function(randomEngine) {
    this.rand = randomEngine;
};

RandomColorPicker.prototype.pickColor = function() {
    return '#' + this.rand() + "" + this.rand() + "" + this.rand();
};

var randHex = function() {
    return (Math.floor(Math.random() * 106) + 150).toString(16);
};

var f = new Main(new RandomColorPicker(randHex));
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top