Reputation: 1065
I've been struggling with this for quite some time and I can't figure out how to resolve this issue.
I'm trying to make a grid directive which contains column directives to describe the grid but the columns won't be elements and would just add the columns to the array that is declared on the scope of the grid directive.
I think the best way to explain this issue is to view view the code:
var myApp = angular.module('myApp', [])
.controller('myCtrl', function ($scope, $http) {
})
.directive('mygrid', function () {
return {
restrict: "E",
scope: true,
compile: function ($scope) {
debugger;
$scope.Data = {};
$scope.Data.currentPage = 1;
$scope.Data.rowsPerPage = 10;
$scope.Data.startPage = 1;
$scope.Data.endPage = 5;
$scope.Data.totalRecords = 0;
$scope.Data.tableData = {};
$scope.Data.columns = [];
},
replace: true,
templateUrl: 'mygrid.html',
transclude: true
};
})
.directive('column', function () {
return {
restrict: "E",
scope: true,
controller: function ($scope) {
debugger;
$scope.Data.columns.push({
name: attrs.name
});
}
};
});
And here is the HTML markup:
<body ng-app="myApp">
<div ng-controller="myCtrl">
<input type="text" ng-model="filterGrid" />
<mygrid>
<column name="id">ID</column>
<column name="name">Name</column>
<column name="type">Type</column>
<column name="created">Created</column>
<column name="updated">Updated</column>
</mygrid>
</div>
In addition, you can test the actual code in jsfiddle: http://jsfiddle.net/BarrCode/aNU5h/
I tried using compile, controller and link but for some reason the columns of the parent grid are undefined.
How can I fix that?
Edit: When I remove the replace, templateUrl, transclude from the mygrid directive, I can get the scope from the column directive.
Thanks
Upvotes: 1
Views: 1510
Reputation: 1065
In the later versions of AngularJS I found that $scope.$$childHead does what I wanted.
It's still new but it works very well also with directive with isolated scopes.
So in the Columns directive you can just do:
$scope.$$childHead.Data.columns.push({
name: attrs.name
});
Just make sure that this command is executed after the compile of the grid. You can do that but switching between compile, link and controller since each one of them has a different loading priority.
Upvotes: 1
Reputation: 8568
As Imri Commented:
In the later versions of AngularJS you can get your parent directive by using $scope.$$childHead
I have not tested it.
Upvotes: 0
Reputation: 12477
I see what you're trying to do, but using a column
directive is probably not the best way to tackle problem.
You're trying to define a grid
directive with customizable columns. The columns each have 2 relevant pieces of information: the key with which to access the value in the row data, and the title to display.
Ignoring for the moment all the pagination-related stuff, here's a different way to approach the problem.
First, let's use attributes to define the column information, so our HTML would look like:
<body ng-app='app' ng-controller='Main'>
<grid col-keys='id,name,type'
col-titles='ID,Name,Type'
rows='rows'>
</grid>
</body>
For the JS, we obviously need the app
module:
var app = angular.module('app', []);
And here's the grid
directive. It uses an isolate scope, but uses the =
2-way binding to get the row data from its parent scope. Notice how the link function pulls the column info from the attrs
object.
The template becomes very simple: loop over the column titles to define the headings, then loop over rows
, and in each row, loop over the column keys.
app.directive('grid', function() {
return {
restrict: 'E',
scope: {
rows: '='
},
link: function(scope, element, attrs) {
scope.colKeys = attrs.colKeys.split(',');
scope.colTitles = attrs.colTitles.split(',');
},
replace: true,
template:
'<table>' +
' <thead>' +
' <tr>' +
' <th ng-repeat="title in colTitles">{{title}}</th>' +
' </tr>' +
' </thead>' +
' <tbody>' +
' <tr ng-repeat="row in rows">' +
' <td ng-repeat="key in colKeys">{{row[key]}}</td>' +
' </tr>' +
' </tbody>' +
'</table>'
};
});
And some sample data to get started.
app.controller('Main', function($scope) {
$scope.rows = [
{id: 1, name: 'First', type: 'adjective'},
{id: 2, name: 'Secondly', type: 'adverb'},
{id: 3, name: 'Three', type: 'noun'}
];
});
Upvotes: 0