The Directive
function CreateTable($http) {
return {
restrict: "E",
scope: true,
templateUrl: function (element, attr) {
return 'Hexdra/partials/' + attr.tableName + '-table.html';
},
link: function(scope, iElement, iAttrs, controller) {
$http.get('Hexdra/app/app_data/' + iAttrs.tableData + '.json')
.success(function (data) {
var vm = scope;
vm.table = data;
});
return vm.table;
}
};
};
The Html
<site-table table-name="goals" table-data="goals"class="span6"></site-table>
The directive creates a table whos template changes based on what the attribute table-name= defined in the Html.
What I am now having trouble with is where to define a function in the directive that uses the $http service to get a JSON file. Which JSON file is selected dipends on the attribute table-data= in the Html.
An example of what the directive should do
Take this html -> <site-table table-name="goals" table-data="goals"></site-table>
And then create a table based off a template located at partials/goals.html and load a JSON file from app_data/goals.json.
Should i create a controller that is assigned to this particular directive?
Please point me in the right direction and let me try to figure it out again, instead of giving me the answer, I will learn more about directives and angular that way.
Thank you :)
EDIT ->
The Solution
With extensive help from the community the issue was solved and here is the general guide if you need to solve the same issue.
The Html
<site-table table-name="goals" table-data="goals"class="span6"></site-table>
The New Angular.js
Setup
angular
.module('table', [])
.controller('TableController', TableController)
.directive('siteTable', CreateTable)
.factory('dataGet', JSONGet)
TableController.$inject = ['dataGet'];
JSONGet.$inject = ['$http'];
The Service
function JSONGet($http) {
return {
getJSON: function (fileName) {
return $http.get(fileName +'json').then(function (result) {
return result.data;
});
}
};
}
Note There are several ways to define a service, this service was defined using a factory.
The Controller
function TableController(dataGet) {
var vm = this;
vm.table = [];
this.getJSON = function (fileName) {
dataGet.getJSON(fileName).then(function (data) {
vm.table = data;
});
}
}
The Directive
function CreateTable() {
return {
restrict: "E",
scope: true,
templateUrl: function (element, attr) {
return 'Hexdra/partials/' + attr.tableName + '-table.html';
},
controller: 'TableController',
controllerAs: 'TblCtrl',
link: function (scope, element, attr, controller) {
controller.getJSON(attr.tableData);
}
};
}
Breaking down the directive
We have a directive that:
Is restricted to an Element, restrict: "E".
Has its own Scope, scope: true.
Has a templateUrl that will be populated with data from our AJAX call. Theres a special part to this TemplateUrl though. We could just have it set to a static unchanging address, partials/myTemplate.html. Instead we pass it a function that has two arguements, element and attribute (attr), this allows us to pull from elements or attributes that are assigned to this directive in the HTML. Its going to return a concatenated address, attr.tableName was an attribute we gave to our table directive and in our HTML we have tableName=goals. What ends up getting set as our templateURL is Hexdra/partials/goals-table.html
We give our directive a controller that has already been defined in the app.
controller: TableController.
We assign that controller a new name.
controllerAs: TblCtrl.
We now use link and pass it a function that contains the scope, elements, attributes, and the controller that is contained within the directive.
This allows us to call the service JSONGet that is within the controller TableController.
So controller.getJSON(attr.tableData) means, find the controller (which is defined as TableController in this directive) find the function .getJSON and pass it what the attribute tableData is defined as in the HTML.
Now we go to the controller
That method .getJSON is here and is actually a function that passes in one arguement fileName which from our directive is attr.tableData. The method is actually part of the dataGet service which takes that passed on fileName parameter passes it to a getJSON function which then uses the built in $http service from angular to make an AJAX call to get the required data to populate the table.
The End Result.
We produce a table that has loaded its own template from whatever table-name is equal to. We also are able to populate the table with a JSON file that pulls its location from a service that uses the table-data attribute dynamically.
You can view the plunkr here, courtesy of Mr. Juarez