ローカルに保存したJSONファイルのインポート
ローカルマシンに保存してあるJSONファイルをfileコントールを使用してインポートを行う方法についてです。
本当はfileコントロールにng-changeを設定できたらいいのですが、残念ながらそれはできませんでした。
コード
HTML
<div ng-controller="SampleCtrl">
<div>
<button ng-click="selectFile()">ファイルのインポート</button>
<input type="file" style="display:none" id="select-file" onchange="angular.element(this).scope().importSelectFile(this)" />
</div>
<p ng-bind="importStr"></p>
</div>
fileコントロールを使うと「ファイル選択」という変更できない文字列のボタンがユーザーに見えてしまうため、styleにdisplay:noneを設定して非表示にしています。代わりに置いたbuttonコントロールを経由してfileコントロールを利用します。
JavaScript
// コントローラー
myApp.controller('SampleCtrl', function ($scope, $timeout) {
// ファイル選択
$scope.selectFile = function(){
angular.element(document.querySelector('#select-file')).click();
};
// インポート
$scope.importSelectFile = function(evt){
// 選択ファイルの読み込み
var file = evt.files[0];
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function(){
// 読み込んだデータをセット
$scope.importStr = reader.result;
if(isJson(reader.result)){
// JSONに変換
$scope.importData = angular.fromJson(reader.result);
}else{
alert("JSONデータではありません。");
}
// 画面リフレッシュ
$timeout(function(){}, 100);
};
// fileコントロールの選択状態をリセット
angular.element(document.querySelector('#select-file')).val(null);
};
// JSONデータの型チェック
function isJson(arg){
try{
JSON.parse(arg);
return true;
}catch(e){
return false;
}
}
});
reader.onload() 実行後に画面の状態が更新されないため、$timeout(function(){}, 100); を使って強制的に画面をリフレッシュしています。
fileコントロールの選択状態をリセットしている理由は、リセットしておかないと同じファイルが選択された場合にonchangeイベントが発生しないためです。