0

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

2
  • what you wan to do with your data.? your question is not clear, if you give more information, i can help you. Commented Apr 24, 2016 at 10:09
  • I have edited the question to better explain. Just how you helped me with defining an attribute so that the template would change based off of an Html attribute, I now need help with using an html attribute in my directive that will effect which JSON data is used to populate the table. I would like a pointer in the right direction rather than a straight answer unless I still cant figure it out. Commented Apr 24, 2016 at 14:14

1 Answer 1

1

You should create a Controller which will manipulate all the data that you are going to show in your view, in your directive you should only have DOM manipulations.

After creating the Controller you should create a service which will have a function that does the $http call.

In the controller you should have an attribute which will be referenced from the html of the directive that will be the data that you are going to display, if that is what you want.

Sign up to request clarification or add additional context in comments.

7 Comments

You can create a controller in a directive, when should one do so?
Sorry, I didn't understand your question. If you are referring when to create a Controller for a directive, you create it when you have to manipulate data that is going to be shown to the user or when you have to get data from other services.
I was wondering about the difference of defining a controller in the directive with the object notation, or defining it outside the directive and the directive is placed inside the controller in the html.
For a better legibility you should have the controller in a different file or section of your file, and only reference it in your directive by the name. The directive has an attribute called controller in which you can assign an already existing controller or a new instance for the directive. You are just going to have a CreateTableController with the call to the service and data manipulation and a service RetrieveJSONService with the $http call
I created a service, and it does a $http.get but the url is static and Im stuck on how to get the HTML attribute table-data into the service so that it is dynamic. For the templateUrl of the directive, I was able to use a function that contained the elements and attributes of the html, is there an equivalent for services?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.