Mawg
Mawg

Reputation: 40155

AngualrJs: ag-grid in a ui-router view (templateUrl)

I had a working app, including a few ag-grids. I decided to add ui-router, with the grids in the templateUrl of a state.

The code is mcuh to large to post, but I have two problems:

I find that currentCandidatesGridDiv is null, despite having

<div ag-grid="SearchResultController.currentCandidatesGrid"></div>

in the HTML of the templateUrl.

Again, not much help to you without full code, which is very, very large.

I guess that what I am looking for is a working code sample, Plunk, etc to show how to put a simple ag-grid into a ui-router state's templateUrl.

Upvotes: 0

Views: 222

Answers (2)

georgeawg
georgeawg

Reputation: 48968

This answer has three parts:

  • Why DOMContentLoaded event listeners fail in controllers
  • Use custom directives to inject code that manipulates DOM
  • DEMO of ag-Grid with AngularJS

Why DOMContentLoaded event listeners fail in controllers

JavaScript libraries that manipulate the DOM need to coordinate with DOM manipulations done by the AngularJS framework.

AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.

document.addEventListener("DOMContentLoaded" is not called when I put it in the controller of the templateUrl

The AngularJS framework initializes itself after the DOMContentLoaded event. So naturally any DOMContentLoaded event listener added afterwards by a controller will miss that event.

One should use caution when mixing AngularJS with third-party libraries that manipulate the DOM.


Use custom directives to inject code that manipulates DOM

When one sees code such as document.querySelector("#myid'), replace that with a custom directive:

app.directive("myDirective", function() {
    return {
        link: postLink
    };
    function postLink(scope, elem, attrs) {
        //DOM initialization here
        //e.g.  initialize(elem);

        scope.$on('$destroy', function() {
            //DOM teardown code here
        });
    }
})

Usage:

<div id="myid" my-directive></div>

AngularJS directives are markers on a DOM element that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element.

When the AngularJS framework adds templates to the DOM, it parses the markup and injects code for the AngularJS directives. When it destroys DOM, it broadcasts a $destroy event on the scope associated with the element.

For more information, see


DEMO of ag-Grid with AngularJS

When the ag-Grid script loads, it does not register with AngularJS 1.x. This is because AngularJS 1.x is an optional part of ag-Grid and you need to tell ag-Grid you want to use it:

agGrid.initialiseAgGridWithAngular1(angular);

angular.module("example", ["agGrid"])

For more information, see

The DEMO

agGrid.initialiseAgGridWithAngular1(angular);

angular.module("example", ["agGrid"])
.controller("exampleCtrl", function($scope) {

    var columnDefs = [
        {headerName: "Make", field: "make"},
        {headerName: "Model", field: "model"},
        {headerName: "Price", field: "price"}
    ];

    var rowData = [
        {make: "Toyota", model: "Celica", price: 35000},
        {make: "Ford", model: "Mondeo", price: 32000},
        {make: "Porsche", model: "Boxter", price: 72000}
    ];

    $scope.gridOptions = {
        columnDefs: columnDefs,
        rowData: rowData
    };

})
    html, body {
        height: 100%;
        width: 100%;
        margin: 0;
        box-sizing: border-box;
        -webkit-overflow-scrolling: touch;
    }
    html {
        position: absolute;
        top: 0;
        left: 0;
        padding: 0;
        overflow: auto;
    }
    body {
        padding: 1rem;
        overflow: auto;
    }
<script src="//unpkg.com/angular/angular.js"></script>
<script src='//unpkg.com/@ag-grid-community/all-modules/dist/ag-grid-community.min.js'>
</script>

<body ng-app="example" ng-controller="exampleCtrl" style="height: 100%">

    <div ag-grid="gridOptions" class="ag-theme-balham" style="height: 100%;">
    </div>

</body>

Upvotes: 1

cody mikol
cody mikol

Reputation: 852

It looks like your actual problem is that you are using a querySelector on the id

#currentCandidatesGrid

# is a selector for an element id

This would only match your element if it had that specified id, which in your example does not exist.

<div ag-grid="SearchResultController.currentCandidatesGrid"></div>

Would need to be

<div id="currentCandidatesGrid" ag-grid="SearchResultController.currentCandidatesGrid"></div>

if you want to get that element via

document.querySelector('#currentCandidatesGrid');

Upvotes: 1

Related Questions