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 to perform basic operations on a DevExtreme widget using the AngularJS framework. Similar articles are available for the jQuery library and the Knockout framework.

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-chart directive creates a dxChart widget, dx-range-selector creates a dxRangeSelector, 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 dxChart widget in a <div> container.

HTML
<div dx-chart=""></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-chart="{ 
    dataSource: [
        { fruit: 'Oranges', total: 10 },
        { fruit: 'Apples', total: 15 },
        { fruit: 'Bananas', total: 9 }
    ],
    series: { argumentField: 'fruit', valueField: 'total' }
 }"></div>
See Also
  • Reference | WidgetName | Configuration - describes all options of a specific DevExtreme widget.

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

JavaScript
function Controller ($scope) {
    $scope.fruitsData = [
        { fruit: 'Oranges', total: 10 },
        { fruit: 'Apples', total: 15 },
        { fruit: 'Bananas', total: 9 }
    ];
}
HTML
<div ng-controller="Controller">
    <div dx-chart="{
        dataSource: fruitsData,
        series: { argumentField: 'fruit', valueField: 'total' }
    }"></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.chartOptions = {
        dataSource: [
            { fruit: 'Oranges', total: 10 },
            { fruit: 'Apples', total: 15 },
            { fruit: 'Bananas', total: 9 }
        ],
        series: { argumentField: 'fruit', valueField: 'total' }
    };
}
HTML
<div ng-controller="Controller">
    <div dx-chart="chartOptions"></div>
</div>

Change Options

One way or another, 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-range-selector="{
        bindingOptions: {
            selectedRange: 'selectedRange'
        }
    }"></div>
</div>
JavaScript
function Controller ($scope) {
    $scope.selectedRange = {
       startValue: 10,
       endValue: 20
    };
}

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 selectedRange 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 fast, but it updates the widget only when an item was 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.fruitsData = [
        { fruit: 'Oranges', total: 10 },
        { fruit: 'Apples', total: 15 },
        { fruit: 'Bananas', total: 9 }
    ];
}

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

HTML
<div ng-controller="Controller">
    <div dx-chart="{
        bindingOptions: {
            dataSource: {
                <!-- Enables deep tracking of changes in a collection -->
                deep: true,
                <!-- Specifies which scope property to deep-track changes in -->
                dataPath: 'fruitsData' 
            }
        },
        series: { argumentField: 'fruit', valueField: 'total' }
    }"></div>
</div>

Call Methods

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

JavaScript
var chartInstance = $("#chartContainer").dxChart("instance");

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

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

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

JavaScript
var series = chartInstance.getAllSeries();
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-chart="{
    . . .
    onLegendClick: handler1,
    onArgumentAxisClick: handler2
 }"></div>
JavaScript
function Controller ($scope) {
    $scope.handler1 = function (info) {
        // Handles the "legendClick" event
    };
    $scope.handler2 = function (info) {
        // Handles the "argumentAxisClick" event
    }
}

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 "legendClick" and "argumentAxisClick" events
chartInstance
    .on({
        "legendClick": handler1,
        "argumentAxisClick": handler2
    });
JavaScript
// Attaches several handlers to the "legendClick" event
chartInstance
    .on("legendClick", handler1)
    .on("legendClick", 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
chartInstance.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 "legendClick" event leaving other handlers (if any) intact
chartInstance
    .off("legendClick", handler1)

// Detaches all handlers from the "legendClick" event
chartInstance
    .off("legendClick")

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

JavaScript
chartInstance.option("onLegendClick", 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
$("#chartContainer").remove();