1

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.

2 Answers 2

3

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

2

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>
2
  • good point about logic in markup... you have bug in test though expect should be true Commented Nov 6, 2013 at 13:01
  • credited both answers. I am going to try this approach with ngClass (returning the state instead of the css class). Commented Nov 6, 2013 at 14:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.