问题
I had a working app, including a few ag-grid
s. 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 templateUrlI guess that I can get round that by moving the enclosed logic into
$transitions.onSuccess({ entering: 'search_result' }, function (transition)
, BUT, when Iconst 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