AngularJSを使用したデータ連結処理で通常より多くの時間を要する

文書番号 : 39618     文書種別 : 不具合     登録日 : 2016/10/03     最終更新日 : 2017/03/29
文書を印刷する
対象製品
SpreadJS 9J
発生環境
9.20161.0
状況
修正済み
詳細
gc-spread-sheetsディレクティブのdatasource属性を用いたデータ連結処理で、sheet.setDataSource()を用いたデータ連結よりも多くの描画完了を要する現象が発生します。

【再現手順】
1.以下の再現コードを実行します

【現象】
後述の回避コードを使用した場合、もしくはsheet.setDataSource()を用いたデータ連結と比較して、多くの描画完了を要する現象が発生します。

【再現コード JavaScript ファイル名test.js】
var app = angular.module('spread-app', ['gcspreadsheets']);
app
  .controller('sjs-ctrl', ['$scope', '$http', function($scope, $http) {
    var initLoad = true;
    angular.element(document).ready(function() {

      // スプレッドウィジェット
      $scope.spread = $("#ss").data("workbook");
      
      //データ連結完了時の処理
      $scope.$watch('model', function(newData, oldData) {
        if (newData != oldData) {
          if (initLoad) {
            // データ読み込み完了
            initLoad = false;
          }
        }
      }, false);

      $http.get("testdata.json").then(
        function(response) {
          //成功時処理
          var bigarr = response.data;
          for (var i = 1; i < 100; i++) {
            var item = $.extend({}, bigarr[i - 1]);
            item.TestData = i + 1;
            bigarr.push(item);
          }
          $scope.model = bigarr;
        },
        function(response) {
          // データ読み込み失敗時の処理
        });
    });
  }]);

【再現コード HTML ファイル名test.html】
<!DOCTYPE html>
<html ng-app="spread-app">
  <head>
    <title>Sample</title>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
    <script type="text/javascript" src="https://code.angularjs.org/1.2.22/angular.min.js"></script>
    <script type="text/javascript" src="https://code.angularjs.org/1.2.22/angular-route.min.js"></script>
    <link href="http://cdn.grapecity.com/spreadjs/9201610/css/gc.spread.sheets.excel2016colorful.9.20161.0.css" rel="stylesheet" type="text/css" />
    <script src="http://cdn.grapecity.com/spreadjs/9201610/scripts/gc.spread.sheets.all.9.20161.0.min.js" type="text/javascript"></script>
    <script src="http://cdn.grapecity.com/spreadjs/9201610/scripts/interop/angular.gc.spread.sheets.9.20161.0.min.js" type="text/javascript"></script>
    <script src="test.js"></script>
    <link rel="stylesheet" type="text/css" href="test.css">
  </head>
  <body>
    <div class="header">
    </div>
    <div class="container" ng-controller="sjs-ctrl">
      <div class="spread">
        <gc-spread-sheets id="ss">
          <worksheets>
            <worksheet datasource="model" name="model">
              <columns>
                <column datafield="TestData">
                </column>
              </columns>
            </worksheet>
          </worksheets>
        </gc-spread-sheets>
      </div>
    </div>
  </body>
</html>

【再現コード JSON ファイル名testdata.json】
[
{
 "TestData": 1
}
]

【再現コード CSS ファイル名 test.css】
div#ss {
 height: 430px;
}
回避方法
SpreadJS 9J SP2(Ver.9.20171.0)で修正済み
SpreadJS 9J SP2(Ver.9.20171.0)より前のバージョンでは次の回避方法が有効です。
------------------------------------------

処理における以下のタイミングでsuspendPaintメソッド、resumePaintをコールします。

・suspendPaintメソッドのコールタイミング:データソース連結前($http.get)
・resumePaintメソッドのコールタイミング:データソース連結後($scope.watch)

【再現コードに対する回避策適用例】
var app = angular.module('spread-app', ['gcspreadsheets']);
app
  .controller('sjs-ctrl', ['$scope', '$http', function($scope, $http) {
    var initLoad = true;
    angular.element(document).ready(function() {

      // スプレッドウィジェット
      $scope.spread = $("#ss").data("workbook");
      
      //データ連結完了時の処理
      $scope.$watch('model', function(newData, oldData) {
        if (newData != oldData) {
          if (initLoad) {
            // データ読み込み完了
            initLoad = false;

            //回避コード(1/2):描画の再開
            $scope.spread.resumePaint();
          }
        }
      }, false);

      $http.get("testdata.json").then(
        function(response) {
          //成功時処理

          //回避コード(2/2):描画の停止
          $scope.spread.suspendPaint();

          var bigarr = response.data;
          for (var i = 1; i < 100; i++) {
            var item = $.extend({}, bigarr[i - 1]);
            item.TestData = i + 1;
            bigarr.push(item);
          }
          $scope.model = bigarr;
        },
        function(response) {
          // データ読み込み失敗時の処理
        });
    });
  }]);