Search code examples
cssangularjsmodelangularjs-service

AngularJS - computing CSS class using plain javascript or a service?


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.


Solution

  • 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>