Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Let's say we are fetching some data from the server.

data = {
"value": "123456",
"included": true,
"invalid": true,
"warning": false,
"error": false,
}

Depending on the booleans state, the value needs to be displayed with a specific style. What I am currently doing is formatting the data into a JS constructor

$scope.model = new SomePrototype(data);

to deduce the CSS you compute the rules (in pseudo code):

var SomePrototype = function (data) {

        this.computeCSS = function () {
        if data.error then css = 'danger'
        if (data.included and data.invalid) then css = 'danger'
        /*other rules*/
        return css
        }
}

then you call computeCSS() in the HTML view

<p class="{{model.computeCSS()}}">{{model.value}}</p> which renders as

`<p class="danger">123456</p>`

ISSUE: first, I haven't seen anything like this elsewhere. So I might do something wrong. Usually you get an object under $scope to hold the class value. Secondly, it requires a call to SomePrototype into each controllers.

I wonder if using a service/factory would be more legal. The end result looks basically the same for me.

share|improve this question
add comment

2 Answers

up vote 2 down vote accepted

You are on the right track however I would use ng-class as charlietfl suggested.

Keeping the logic inside of a function like you mentioned you are able to unit test your rule of what is considered an invalid state of the model. (your conditional is simple, but having logic in your view is usually not ideal)

Model

var SomePrototype = function (data) {

    this.isDataInValid = function () {
        return data.error || data.included && data.invalid;
    }
}

Test

it('should be invalid with error or included && invalid', function () {

    var data = {
        "value": "123456",
        "included": true,
        "invalid": true,
        "warning": false,
        "error": false,
    }
    var someModel = new SomePrototype(data);
    var isDataInValid = someModel.isDataInValid();
    expect(isDataInValid).toBe(true);
});

In your <html/>

<p ng-class="{danger : model.isDataInValid() } ">{{model.value}}</p>
share|improve this answer
    
good point about logic in markup... you have bug in test though expect should be true –  charlietfl Nov 6 '13 at 13:01
    
fixed the test and the resulting markup. –  Mark Coleman Nov 6 '13 at 13:05
    
credited both answers. I am going to try this approach with ngClass (returning the state instead of the css class). –  mahery rafara Nov 6 '13 at 14:38
add comment

You don't need a function to set class based on scope values, use ng-class which accepts some javascript conditionals

<p ng-class="{danger: data.error || data.included && data.invalid} ">{{data.value}}</p>

function Ctrl($scope) {
    $scope.data = {
        "value": "123456",
            "included": true,
            "invalid": true,
            "warning": false,
            "error": false,
    }
}

DEMO

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.