Widget Basics - AngularJS

NOTE
This article assumes that you have successfully linked all the necessary scripts. If not, read the Installation guide first.

From this article, you will learn how to perform basic operations on a DevExtreme widget using the AngularJS framework. Similar articles are available for the jQuery library and the Knockout framework.

DevExtreme UI widgets can be used in applications built using the AngularJS version 1.2 and 1.3.

NOTE
If you use AngularJS version 1.3, pay attention to the Migration Guide.

Create and Configure a Widget

For operating with AngularJS, DevExtreme includes an AngularJS module registered under the name "dx". Add it to the list of dependencies for your application module.

JavaScript
angular.module('myApp', [ 'dx' ]);

The "dx" module contains directives that you use to create any DevExtreme widget. For instance, the dx-button directive creates a dxButton widget, dx-range-slider creates a dxRangeSlider, etc. Note that all DevExtreme directives satisfy the AngularJS normalization rules: dx-widget-name.

Any DevExtreme directive should be associated with a <div> HTML element, which plays the role of a container for the widget. For example, the following code creates a dxMenu widget in a <div> container.

HTML
<div dx-menu=""></div>

To configure a widget, pass an object to the widget directive. Note that the properties of this object mirror the options of the widget.

HTML
<div dx-menu='{ 
    dataSource: [
        {
            text: "Guides",
            items: [
                { text: "VS Integration" },
                { text: "UI Widgets" },
                { text: "Data Visualization" },
                { text: "Data Layer" }
            ]
        },
        . . .
    ],
    selectByClick: true
 }'></div>
See Also
  • Reference | WidgetName | Configuration - describes all options of a specific DevExtreme widget.

You can initialize widget options with the value of a scope property. For example, the following code declares the menuItems property within the scope of a controller. The dataSource option of a dxMenu is initialized with the value of this property.

JavaScript
function Controller ($scope) {
    $scope.menuItems = [
        {
            text: "Guides",
            items: [
                { text: "VS Integration" },
                { text: "UI Widgets" },
                { text: "Data Visualization" },
                { text: "Data Layer" }
            ]
        },
        . . .
    ];
}
HTML
<div ng-controller="Controller">
    <div dx-menu="{
        dataSource: menuItems,
        selectByClick: true
    }"></div>
</div>
NOTE
Initializing widget options in this manner does not mean that the widget option will be changed once its scope property is changed. If you are looking for this kind of data binding, refer to the Change Options topic.

As an alternative, you can declare the whole object of widget options in the scope and pass it to the widget directive.

JavaScript
function Controller($scope) {
    $scope.menuOptions = {
        dataSource: [
            {
                text: "Guides",
                items: [
                    { text: "VS Integration" },
                    { text: "UI Widgets" },
                    { text: "Data Visualization" },
                    { text: "Data Layer" }
                ]
            },
            ...
        ],
        selectByClick: true
    };
}
HTML
<div ng-controller="Controller">
    <div dx-menu="menuOptions"></div>
</div>

Watch Video

Change Options

All operations with widget options are carried out through the scope properties these options are bound to. To bind a widget option to a scope property, use the bindingOptions object as shown in the following code.

HTML
<div ng-controller="Controller">
    <div dx-menu="{
        . . .
        bindingOptions: {
            disabled: 'disabledValue'
        }
    }"></div>
</div>
JavaScript
function Controller ($scope) {
    . . .
    $scope.disabledValue = false;
}

Now, if you change a scope property in code, the widget will catch up the changes. And vice versa, if an end user changes the selected range in the UI, the disabledValue scope property will be updated.

NOTE
The names of scope properties in the bindingOptions object should be enclosed in quotes.

If you bind a widget option to a collection in the same manner, the widget uses the $watchCollection watcher to track changes in the collection. This watcher works quickly, but it updates the widget only when an item is added or removed from the collection. To track changes made directly in the items, activate the $watch watcher. For example, assume that you have an array assigned to a scope property.

JavaScript
function Controller($scope) {
    $scope.mapMarkers = [
        {
            location: "40.749825, -73.987963",
            tooltip: "New York"
        },
        {
            location: "45.478502, 9.158304",
            tooltip: "Milano"
        },
        {
            location: "-3.007118, 37.138956",
            tooltip: "Kilimanjaro"
        }
    ];
}

To enable deep tracking of changes in this array, the bindingOptions object should look as follows.

HTML
<div ng-controller="Controller">
    <div dx-map="{
        bindingOptions: {
            markers: {
                <!-- Enables deep tracking of changes in a collection -->
                deep: true,
                <!-- Specifies which scope property to deep-track changes in -->
                dataPath: 'mapMarkers'
            }
        }
    }"></div>
</div>

Watch Video

Call Methods

To call a method, you need to obtain the widget instance first. You can use jQuery to do this.

JavaScript
var menuInstance = $("#menuContainer").dxMenu("instance");

As an alternative, you can save the widget instance in a scope property once the widget is initialized.

JavaScript
function Controller ($scope) {
    $scope.menuInstance = {};
    $scope.menutOptions = {
        // ...
        onInitialized: function (e) {
            $scope.menuInstance = e.component;    
        }
    };
}

After that, you can call any method of the saved instance.

JavaScript
menuInstance.repaint();
See Also
  • Reference | WidgetName | Methods - describes all methods of a specific DevExtreme widget.

Handle Events

Subscribe to an Event

You can subscribe to an event using a configuration option. All event handling options are given names that begin with on.

HTML
<div dx-menu="{
    . . .
    onItemClick: handler1,
    onSelectionChanged: handler2
 }"></div>
JavaScript
function Controller ($scope) {
    $scope.handler1 = function (info) {
        // Handles the "itemClick" event
    };
    $scope.handler2 = function (info) {
        // Handles the "selectionChanged" event
    }
}
NOTE
You can obtain the widget instance, using the component field of the event arguments object.
JavaScript
function Controller ($scope) {
    . . .
    $scope.handler2 = function (info) {
        DevExpress.ui.notify("The " + info.component.option("value") + " was selected", "success", 3000);
    }
}

As a more flexible solution, you can use the on() method. It allows you to subscribe to events at runtime and even to attach several handlers to a single event.

JavaScript
// Subscribes to the "itemClick" and "selectionChanged" events
widgetInstance
    .on({
        "itemClick": handler1,
        "selectionChanged": handler2
    });
JavaScript
// Attaches several handlers to the "itemClick" event
chartInstance
    .on("itemClick", handler1)
    .on("itemClick", handler2);
NOTE
In case you need information about calling methods, see the Call Methods topic.

Unsubscribe from an Event

To detach all the handlers that you attached with the on() method, call the off() method without arguments.

JavaScript
widgetInstance.off();

Also, you can call this method to detach a specific handler from an event or all handlers from a particular event.

JavaScript
// Detaches the "handler1" from the "itemClick" event leaving other handlers (if any) intact
chartInstance
    .off("itemClick", handler1)
JavaScript
// Detaches all handlers from the "itemClick" event
chartInstance
    .off("itemClick")

If you subscribed to an event using an onEventName option, you can unsubscribe from it by setting this option to undefined.

JavaScript
widgetInstance.option("itemClick", undefined);
See Also
  • Reference | WidgetName | Events - describes all events of a specific DevExtreme widget.

Destroy a Widget

To destroy a DevExtreme widget, remove the DOM node associated with this widget.

JavaScript
$("#menuContainer").remove();