1

I have a multi-dimensional array being injected into my view scope that contains attendance data for students. Essentially, it’s a digital attendance sheet reflecting many records. I’m using angularjs to make XHR calls that can modify individual records asynchronously.

Problem: Once I modify an individual record, for instance: changing an A (absent) to a P (present) via ajax, I’d like to add or remove a css class for that particular table cell. However, directives execute upon binding, and I need it to execute after I’ve modified a record via ajax, long after data has bound.

This was fairly easy to accomplish in the controller using jQuery, right there within the PUT calls success function. But this isn’t the ‘angular way’ to modify the dom. However, from what I’ve read apparently it’s also bad practice to modify DOM after binding. Surely there’s a way to do this ‘right’ with angular… I was hoping you guys could add some clarity. Ideas much appreciated.

Here's the PUT call in the controller, which goes through and modifies the scope appropriately after the PUT completes, then uses the jQuery I mentioned prior to change the cell:

$http.put("/api/attendance/PutAttendRecord/", stuInfo)
.then(function (d) {
    var dt = d.data.class_date_am;
    var dc = d.data.dc_number;
    var st = d.data.status_am;

    $scope.classlist.forEach(function (obj) {
        if (dc == obj.DcNumber) {
            obj.Attend.forEach(function (attObj) {
                if (dt == attObj.ClassDate) {
                    var el = $scope.thisElement.parentNode;

                    if ($(el).hasClass("statusupdated")) {
                        $(el).removeClass("statusupdated");
                    } else { $(el).addClass("statusupdated"); }

                    attObj.Status = st;
                }
            })
        }
    })
})

Here's the directive, which as of now isn't accomplishing anything except a console log.

var updateRecord = function () {

    var directive = {
        link: link
    }
    return directive;
    function link(scope, element, attrs) {
        console.log(element.val());
    }
}

app.controller("ModifyRecordController", ModifyRecordController)
.directive("updateRecord", updateRecord);

Thanks!

georgeawg
  • 48,608
  • 13
  • 72
  • 95
silencedogood
  • 3,209
  • 1
  • 11
  • 36
  • 4
    Use the [ng-class directive](https://docs.angularjs.org/api/ng/directive/ngClass) to dynamically set CSS classes on an HTML element by databinding an expression. – georgeawg Jul 31 '18 at 14:51
  • Thanks @georgeawg However, ngClass doesn't work here (unless I'm missing something), because I have multiple elements within an ngRepeat directive, and using ngClass applies the class change to all td elements because of this. I only want the class to be applied to the td element that contains the record that was just modified (PUT call). Any ideas? I may need to create a jsfiddle and re-post question in order to add clarity. – silencedogood Aug 01 '18 at 13:53
  • The whole idea behind Angular (and other MVC implementations) is to keep the display separate from the data. So, in your data, set a property that indicates which data items should have the class. Then in your ngClass have it set the class when that property indicates it should. The duplicate notes how to do that. – Heretic Monkey Aug 01 '18 at 15:49

0 Answers0