AngularJS and DOM Manipulation

Tuesday, February 19, 2013

One of the nicer features of Angular is the framework's ability to separate the roles of the model, the view, and the controller. The separation is clean enough that you shouldn't need to manipulate the DOM directly from code inside the controller. Instead, the controller only manipulates the model, which influences the view through data bindings and directives.  The end result is a clean and testable.

In the last post we saw how to build a simple tabular display with Angular and the Web API, but in my original non-Angular sample I also had a "Create Video" button that would open a form with inputs for the user to enter new video information. This was all achieved using jQuery to wire up click event handlers and using jQuery to find DOM elements by ID, then using jQuery to toggle visibility. With AngularJS none of the jQuery code is needed.

Let's add the following HTML inside the ng-app div from the previous post:

<button ng-click="showEdit">Create Video</button>

<div ng-show="isEditVisible">
    <hr />
    <form>
        <input type="hidden" name="id" value =""/>
        <label for="title">Title:</label>            
        <input type="text" name="Title" value="" />
        <!-- more inputs... -->
       
    </form>
</div>

Pay no attention to what is inside the form just yet. The focus of this post is the ng-click and ng-show directives. Directives in Angular are programmable components that can perform specific tasks to make the application more declarative and easy to maintain and test.

The ng-click directive, as you might suspect, is a directive containing an expression for Angular to evaluate against the current controller scope when the user clicks the button. The ng-show directive contains an expression that will determine the visibility of an element. If isEditVisible is truthy the element will be visible, if falsy the element will dissapear. There is also an ng-class directive to set CSS classes on an element, so these directives help you stay "hands off" the DOM from a controller. There are additional directives available, and you can always plug in custom directives.

With the HTML in place, we only need a few lines of code in the controller to hide the form on load, and show the form when a user clicks the button.

var VideoController = function ($scope, $http) {

    $scope.isEditVisible = false;

    $scope.showEdit = function () {
        $scope.isEditVisible = true;
    };
   
    $http.get('/api/videos/').success(function (data) {
        $scope.videos = data;
    });

};

Fans of XAML and the MVVM pattern might see some similarities in how Angular's MVC approach works. One significant difference to me is the clean markup compared to XAML. I always felt bad when I saw the ceremony of  {Bindingicus Pathius=isEditVisible , Converteralicus={StaticusResourcious visibilityFromBool}} in XAML.


Comments
gravatar Diego Tuesday, March 19, 2013
Nice post. About the XAML verbosity, it's trivial to create a markup extension that allows writing Visibility="{ShowIf IsEditVisible}"
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!