AngularJS experts are always saying direct dom manipulation should only happen inside directives. I’ve never studied exactly why that’s important, but I assume it has to do with Angular creating and destroying elements in the background according to its state and digest cycles.
So, if we want to do some fancy dom manipulation with jQuery, then we need to wrap it in a directive, and hopefully make the way it functions semantic and declarative. Here’s an example I can probably make better once I’m more experienced.
angular.module("myModule")
.directive("statusDiv", function($timeout) {
return {
restrict : "A",
link : (scope, element, attrs) => {
const el = $(element);
el.addClass("bg-transition");
scope.$watch(()=>{return attrs.status}, function(newValue, oldValue) {
const infoColor = "#cce4ff";
const warningColor = "#fff8c1";
const successColor = "#8aff59";
const failureColor = "#ffa5a5";
switch (newValue) {
case "loading":
el.css("background-color", infoColor );
break;
case "failed-once":
el.css("background-color", warningColor );
break;
case "success":
el.css("background-color", successColor );
$timeout(function() {
el.css("background-color", "transparent");
}, 2000)
break;
case "failed-all":
el.css("background-color", failureColor );
break;
case "done":
el.fadeOut(2000);
break;
default:
el.css("background-color", "transparent");
break;
}
})
}
}
});
This directive assigns imperative changes in the view to semantic status words like “success”. For this to work nicely, I have also established a CSS transition on these elements. That causes the changes in background-color to transition over 2 seconds. With this in place, all we have to do is declare a status-div directive on an element and include an attribute data-status = “{{ status }}”. Then we can fire off these view effects by changing the value of a semantic element in scope: status = “loading” or status = “failed-all”.
I’m not the best at AngularJS or jQuery yet, but I do know I like a clear division between view logic and business logic, and I like declarative programming. So this is a nice way to add some fancy presentation and wire it up to semantic business logic. See: when used correctly we should set status = “loading” not because we want to cause the visual effect established in the directive, but because “loading” is semantically correct—something is in fact loading. To change what happens to indicate that visually, we change the directive.
Also, the entire breadth of jQuery’s power is at our disposal here inside the directive. We could have done many more things besides just altering background colors.
Now…strange as it sounds considering I’ve written so much Vue, I’m not sure of the best way to do something like this in Vue. That sounds like a good Part 3.