【问题标题】:Initiating directive from controller从控制器发起指令
【发布时间】:2014-04-19 11:25:48
【问题描述】:

一旦数据返回,我无法找到启动指令的方法。我正在尝试使用 html 表和 ng-repeat 构建报告。报表对象是使用工厂生成的。工厂方法返回报告对象,然后 ng-repeat 构建表格。我找到了一个 DataTable 的指令,它采用 html 并应用 JQuery 插件。

问题:如果在创建表之前调用 datatables 指令,它会失败。我需要控制指令何时调用函数element.getTable(options)

我找到了另一个指令,它能够使用$last 确定何时完成 ng-repeat,但有没有办法使用该 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);
                }
            )
        }
    }
});

【问题讨论】:

  • 您能否详细说明您使用 DataTable 指令的原因以及您的“myTable”指令的用途是什么?您是否只想显示从您的工厂返回的数据?
  • 我喜欢这个插件的功能,并且这个指令允许我增强我的 html 报告的功能。
  • 你检查过 ng-grid 吗?
  • 我有,不过我更喜欢 DataTables 的功能。
  • 那么您使用的是哪个 dataTable 指令?我看到你使用的是 jQuery 版本的 dataTable。

标签: javascript angularjs angularjs-directive angularjs-ng-repeat angularjs-controller


【解决方案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 的情况下完全控制最后一步的启动时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 2017-06-05
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    相关资源
    最近更新 更多