Инициирование директивы от контроллера

У меня возникли проблемы с поиском способа инициировать директиву после возврата данных. Я пытаюсь построить отчет, используя html-таблицы и ng-repeat. Объект отчета создается с использованием Factory. Фабричный метод возвращает объект отчета, а ng-repeat строит таблицу. Я нашел директиву DataTable, которая берет html и применяет плагин JQuery.

Проблема: если директива datatables вызывается до создания таблицы, происходит сбой. Мне нужно контролировать, когда директива вызывает функцию element.getTable(options).

Я нашел еще одну директиву, которая может определить, когда ng-repeat выполняется с помощью $last, но есть ли способ использовать эту директиву ngRepeat для инициации директивы dataTables из контроллера?

HTML:

<!-- partials/reports/limbo.html -->
<div ng-visible="$root.ReportReady">
    <table data-name="CheckedOutFiles_Report" class="report" my-table>
        <thead>
            <tr class="reportHeader" >
                <th>Filename</th>
                <th>File Url</th>
                <th>Checked Out To</th>
                <th>Modified</th>

            </tr>           
        </thead>
        <tbody>
            <!-- new row for every file -->
            <tr ng-repeat="file in ReportModel.report" on-finish-render>
                <td>{{file.fileName}}</td>
                <td>{{file.fileUrl}}</td>
                <td>{{file.checkedTo}}</td>
                <td>{{file.modified}}</td>
            </tr>
        </tbody>
    </table>    
</div>

Контроллер отчетов:

spApp.controller('limboReportCtrl', 
    function limboReportCtrl($scope,$q,UserService,GroupService, SiteService, ReportService){

        $scope.ReportModel = {};

        $scope.createReport = function (){
            ReportService.CheckedOutFiles().then(function (data){
                console.log(data);
                $scope.ReportModel.report = data;
            })
        }
        $scope.createReport();

        $scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
            //you also get the actual event object
            //do stuff, execute functions -- whatever...
            console.log('somethingsomething');
        });
    }
);

Директива для обработки функции обратного вызова при выполнении ng-repeat:

spApp.directive('onFinishRender', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit('ngRepeatFinished');
                });
            }
        }
    }
}); 

Директива DataTables:

spApp.directive('myTable', function ($rootScope, $timeout) {
    return {
        restrict: 'E, A, C',
        link: function (scope, element, attrs, controller) {
            var reportName = $(this).data('name');
            //DATA TABLE OPTIONS 


            //THIS WORKS BUT RELIES ON A SET TIME TO CALL DATATABLES AND ISN'T DEPENDENT ON WHEN THE TABLE IS READY. IF CALLED BEFORE TABLE GENERATED, IT WILL NOT WORK
            var timer = $timeout(function (){
                console.log('calling dataTables');
                var dTable = element.dataTable(scope.options);
                new $.fn.dataTable.FixedColumns( dTable );
                $rootScope.ReportReady = true;
            },3000);

            //BEFORE THE CODE BELOW, $TIMEOUT DESTROYED PERFORMANCE OF THE ENTIRE APPLICATION. FOLLOWING THIS BLOG POST, PERFORMANCE SIGNIFICANTLY IMPROVED http://tinyurl.com/naouvv7
            timer.then(
                function (){
                    console.log("Timer resolved ", Date.now());
            },
                function (){
                    console.log("Timer rejected ", Date.now());
                }
            );

            scope.$on('$destroy',
                function(e){
                    $timeout.cancel(timer);
                }
            )
        }
    }
});

comment
Можете ли вы уточнить, почему вы используете директиву DataTable, а также для какой цели служит ваша директива myTable? Вы просто хотите отобразить данные, возвращенные с вашего завода?   -  person mithun_daa    schedule 19.04.2014
comment
Мне нравится функциональность этого плагина, и эта директива позволяет мне улучшить функциональность моих html-отчетов.   -  person Batman    schedule 19.04.2014
comment
Вы проверили ng-grid?   -  person mithun_daa    schedule 19.04.2014
comment
Однако я предпочитаю функциональность DataTables.   -  person Batman    schedule 19.04.2014
comment
Итак, какую директиву dataTable вы используете? Я вижу, что вы используете версию dataTable для jQuery.   -  person mithun_daa    schedule 19.04.2014
comment
Да, я использую jQuery DataTables. Кто-то превратил его в библиотеку jQuery. Это хорошо работает с моим приложением, мне просто нужно лучше контролировать, когда оно срабатывает. В настоящее время я пытаюсь использовать свойство $watch и $rootScope для его запуска. Я обновлю, если это сработает.   -  person Batman    schedule 19.04.2014
comment
Если вы владеете Mastering Web Application Development with AngularJS, у вас есть аккуратный небольшой раздел о том, как обернуть плагины jQuery внутри Angular.   -  person mithun_daa    schedule 19.04.2014


Ответы (1)


Решил это, изменив директиву для dataTables:

        scope.$watch(
            function() {return $rootScope.ReportReady}, 
            function (newValue, oldValue){
            if(newValue){
                console.log('calling dataTables');
                var dTable = element.dataTable(scope.options);
                new $.fn.dataTable.FixedColumns( dTable );
                $rootScope.ReportVisible = true;
            }
        })

В контроллере:

    $scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
        //set a variable to true which datatables directive is watching
        //when that variable is true, initiate datatables
        $rootScope.ReportReady = true;
    });

Поэтому, когда страница отображается и выполняется ng-repeat, она изменяет свойство rootScope. директива наблюдает за этим свойством и видит, что оно изменилось, поэтому вызывает функцию для создания таблицы. Итак, теперь у меня есть полный контроль над тем, когда инициируется этот последний шаг, без использования $timeout.

person Batman    schedule 19.04.2014