Anders
Anders

Reputation: 17554

Angular is rendering directive outside of table

We are using Angular 1.3.15 I have an element directive like

(function () {
    var controller = function ($scope, $timeout) {
        this.$timeout = $timeout;
        $scope.$watch("vm.spinning", this.throttle.bind(this));
    };

    controller.prototype = {
        throttle: function (spinning, oldValue) {
            if (spinning === oldValue) return;

            this.$timeout.cancel(this.timeout);
            if (spinning) {
                this.timeout = this.$timeout(this.setSpinning.bind(this), 100);
            } else {
                this.setSpinning();
            }
        },
        setSpinning: function() {
            this.spinningThrottled = this.spinning;
        }
    };

    myapp.controller("SpinnerController", ["$scope", "$timeout", controller]);

    myapp.directive("spinner", function () {
        return {
            restrict: "E",
            scope: {
                spinning: "=",
            },
            replace: true,
            controller: "SpinnerController",
            controllerAs: 'vm',
            bindToController: true,
            templateUrl: "Views_App/Components/Spinner.html"
        };
    });

    myapp.directive("spinnerGrid", function () {
        return {
            restrict: "E",
            scope: {
                spinning: "=",
            },
            replace: true,
            controller: "SpinnerController",
            controllerAs: 'vm',
            bindToController: true,
            templateUrl: "Views_App/Components/SpinnerGrid.html"
        };
    });
})();

The spinner grid template

<tr data-ng-if="vm.spinningThrottled">
    <td colspan="100">
            <i class="fa fa-spinner fa-spin"></i> Please wait...
    </td>
</tr>

Usage

<table>
   <thead>...</thead>
   <tbody>
      <spinner-grid spinning="searching"></spinner-grid>
      <tr ng-repeat="...">..</tr>
   </tbody>
</table>

For somereason the content of the directive is moved outside of the table?

edit: The question might be a duplicate, but K.Toress answer is not since it utilizes EA restriction

Upvotes: 2

Views: 1098

Answers (1)

Kalhan.Toress
Kalhan.Toress

Reputation: 21901

I think its a normal behavior of the table, if there is a div or any other tag (excluding <tr>) inside a table without inside of a <td> it will remove that and place it on the table.

In your case when html rendering time (which is before the angular executes its scripts) html detects there is a unappropriated tag inside the table which is not inside a td it will remove and place on top of the table, Then when the angular execution time the directive element is not inside the table instead it will top of the table. that's why its render on top of the table.

Please check you can do something like this,

<tbody>
  <tr  data-ng-if="vm.spinningThrottled"><spinner-grid spinning="searching"></spinner-grid></tr>
  <tr ng-repeat="...">..</tr>
</tbody>

SpinnerGrid.html

<td colspan="100">
    <i class="fa fa-spinner fa-spin"></i> Please wait...
</td>

or check this one

directive as a attribute of the <tr>

<tbody>
  <tr spinner-grid spinning="searching"></tr>
  <tr ng-repeat="...">..</tr>
</tbody>

change the directive definition to support the directive as a attribute. restrict: "EA".

myapp.directive("spinnerGrid", function () {
    return {
        restrict: "EA",
        scope: {
            spinning: "=",
        },
        replace: true,
        controller: "SpinnerController",
        controllerAs: 'vm',
        bindToController: true,
        templateUrl: "Views_App/Components/SpinnerGrid.html"
    };
});

Upvotes: 4

Related Questions