69

コントローラーでは、$http または $resource サービスを使用して JSON データを取得します。次に、このデータを $scope に書き込むと、AngularJS がページの HTML 構造を更新します。ng-repeat私の問題は、Angularディレクティブで埋められたリスト (つまり、HTML DOM 要素) の新しいサイズ (幅と高さ) を知る必要があることです。したがって、Angular が DOM 構造の更新を終了した直後に、javascript コードを実行する必要があります。それを行う適切な方法は何ですか?過去 4 時間にわたってインターネットを検索しましたが、問題の解決策が見つかりませんでした。

これは、JSON データを受け取る方法です。

var tradesInfo = TradesInfo.get({}, function(data){
    console.log(data);
    $scope.source.profile = data.profile;
            $scope.trades = $scope.source.profile.trades;
        $scope.activetrade = $scope.trades[0];
        $scope.ready = true;


    init();  //I need to call this function after update is complete

});

そして、これはinit()関数で何が起こるかです:

function init(){
    alert($('#wrapper').width());
    alert($('#wrapper').height());
}

この問題を簡単に解決できる何かがあるに違いないことはわかっていますが、今はそれを見つけることができません。前もって感謝します。

4

4 に答える 4

5

JQuery を使用するための別の提案。ディレクティブで生成されたグリッドに対してこれを処理する必要がありました。グリッド内の特定の行までスクロールしたかったのです。$emit を使用して、ディレクティブから親コントローラーにブロードキャストします。

コントローラーで:

    ['$timeout',function($timeout){
...
 $scope.$on('dataloaded', function () {
            $timeout(function () { // You might need this timeout to be sure its run after DOM render.
                $scope.scrollToPosition();
            }, 0, false);
        });
        $scope.scrollToPosition = function () {
            var rowpos = $('#row_' + $scope.selectedActionID, "#runGrid").position();
            var tablepost = $('table', "#runGrid").position();
            $('#runGrid').scrollTop(rowpos.top - tablepost.top);
        }

ディレクティブで

.directive('runGrid',['$timeout', function ($timeout) {
        // This directive generates the grip of data
        return {
            restrict: 'E',  //DOM Element
            scope: {    //define isolated scope
                list: '=',   //use the parent object
                selected: "="
            },

            templateUrl: '/CampaignFlow/StaticContent/Runs/run.grid.0.0.0.0.htm',  //HTML template URL

            controller: ['$scope', function ($scope) {  //the directive private controller, whith its private scope
                //$scope.statusList = [{ data_1: 11, data_2: 12 }, { data_1: 21, data_2: 22 }, { data_1: 31, data_2: 32 }];
                //Controller contains sort functionallity

                $scope.sort = { column: null, direction: 1 }
                $scope.column = null;
                $scope.direction = "asc";
                $scope.sortColumn = function (id) {
                    if(id!=$scope.column) {
                        $scope.column = id;
                        $scope.direction = "asc";
                    } else {
                        $scope.column = null;
                    }
                }
                $scope.toggleDir = function () {
                    $scope.direction = ($scope.direction == "asc") ? "desc" : "asc";
                }
               $scope.$emit('dataloaded');
            }]


        };
    }])

これは、グリッド ディレクティブの HTML テンプレートのスニペットです。

 <div style="overflow-y:auto;height: 200px;" id="runGrid">
            <table class="table table-striped" style="table-layout:fixed">
           <tbody>
                <tr  ng-repeat="status in list" id="row_{{status.action_id}}" ng-class="(status.action_id==selected)?'selected':''">
                    <td>

リストと選択されたパラメーターは、ディレクティブを使用している html から注入されます

<run-grid list="list" selected="selectedActionID"></run-grid>
于 2014-04-01T11:34:52.820 に答える
3

別の回答を追加したいと思います。前の回答では、ngRepeat の実行後に実行する必要があるコードは角度のあるコードであると見なされているためです。ダイジェスト ライフ サイクル ステージが重要な場合は、Ben Nadel のブログを参照してください。ただし、$eval の代わりに $parse を使用することは例外です。

しかし、私の経験では、OP が述べているように、通常、最終的にコンパイルされた DOM でいくつかの jQuery プラグインまたはメソッドを実行していsetTimeoutますsetTimeout。ブラウザのキューの最後で、Angular ですべてが完了した直後に、通常はng-repeat親の postLinking 関数の後に続きます

angular.module('myApp', [])
.directive('pluginNameOrWhatever', function() {
  return function(scope, element, attrs) {        
    setTimeout(function doWork(){
      //jquery code and plugins
    }, 0);        
  };
});

なぜ $timeout を使用しないのか疑問に思っている人にとっては、まったく不要な別のダイジェスト サイクルが発生するからです。

編集:

ダイジェストを発生させずに $timeout を使用する方法へのリンクを提供してくれた drzaus に感謝します

于 2015-12-30T15:31:35.530 に答える