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

江枫思渺然 提交于 2021-02-05 11:33:05

问题


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:

  • document.addEventListener("DOMContentLoaded" is not called when I put it in the controller of the templateUrl
  • I guess that I can get round that by moving the enclosed logic into $transitions.onSuccess({ entering: 'search_result' }, function (transition), BUT, when I

    const currentCandidatesGridDiv = document.querySelector('#currentCandidatesGrid');
    new agGrid.Grid(currentCandidatesGridDiv, Self.currentCandidatesGrid);
    

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.


回答1:


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');



回答2:


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

  • AngularJS Developer Guide - Creating Custom Directives

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

  • Ag-Grid Documentation - Basic AngularJS 1.x Example

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>


来源:https://stackoverflow.com/questions/60475420/angualrjs-ag-grid-in-a-ui-router-view-templateurl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!