問題
Adobe Creative SDK を Angular アプリに統合しようとしています。エディターは、ボタンをクリックしてフォト ビューアー モーダルから初期化されます。これにより、以下の関数がトリガーされます。エディターが初期化されると、onReady
コールバックによってフォト ビューアーの要素が非表示になり、エディターがモーダルに追加されます。この部分はうまく機能します。
私のモーダルDOMでは、エディターが開いているかどうかに応じて、表示または非表示にしたい要素を使用しようng-show="editorOpen"
としています。ng-show="!editorOpen"
初めてトリガーすると、期待どおり$scope.editPhoto
にng-show
動作します。ただし、エディターを閉じるとng-show
、DOM の更新に失敗します。エディターは非表示になりますが、非表示のフォト ビューアー要素は非表示のままです。
私は Angular のダイジェスト サイクルの専門家ではありませんが、私の調査からわかったことから、ダイジェスト サイクル中にhidePreview()
および関数が呼び出され、への変更が登録されないことが問題であると考えています。showPreview()
ng-show
$scope.editorOpen
エディターを閉じてng-show
DOM の更新に失敗した場合でも、アプリ内でダイジェスト サイクルをトリガーする別のアクションを実行することで手動でトリガーできます。たとえば、左右の矢印キーを使用して次の写真に移動しようとするなどです。ビューアモーダル。
しかし、ここからさらに奇妙になります。エディターを閉じて手動でダイジェストをトリガーすると、すべてが正常に見えます。エディターをもう一度開くと、ng-show
先ほど説明した方法を使用してダイジェストを手動でトリガーしようとしても、完全に機能しなくなります。
私が試した解決策
問題を解決するためにこのディスカッションで提供されたすべての解決策を含め、可能な修正をいくつか試しましたが、すべて失敗しました。
- ダイジェストをトリガーする必要があるため、関数でラップ
$scope.editorOpen = true
してみました。遅延を0msと10msに設定してみました。どちらも失敗しました。$scope.editorOpen = false
$timeout
- 以下のコードにあるおよび関数の代わりに、
$scope.toggleEditor
トグルするスコープ関数を作成し、$scope.editorOpen
それを Adobe Creative SDK 画像エディターのonSave
、onReady
、およびコールバックに渡しました。それも失敗しました。onClose
showPreview()
hidePreview()
$scope.editPhoto
関数全体を関数にラップしてみました$timeout
。また、失敗しました。- 関数内
$scope.$apply()
だけでなく、手動で呼び出すというより直接的なアプローチを試みました。これは通常、エラーが発生する前に一度だけ機能し、悪い習慣のような匂いがします。$scope.$digest()
showPreview()
hidePreview()
$rootScope:inprog
- 最後に、もっと必死になっ
if (!$scope.$$phase) $scope.$apply()
て、ひどい習慣にもかかわらず、問題が解決するかどうかを確認するために を試しました。当然のことながら、#4 と同様に失敗しました。
コード
私のコントローラーには、次の機能があります。
$scope.editPhoto = function(img, key, currentIndex) {
var index = currentIndex;
var photo = img;
var apiKey = key;
var ImgID = angular.element('#image-' + photo.id).children().first();
var ImgSrc = ImgID.attr('src');
if(!$scope.featherEditor) {
$scope.featherEditor = new Aviary.Feather({
apiKey: angular.element('#view_photo').attr('key'),
appendTo: angular.element('#view_photo'),
enableCORS: true,
displayImageSize: true,
showWaitIndicator: true,
onLoad: function() {
launchEditor(ImgID, ImgSrc);
},
onReady: hidePreview(),
onSave: function(imageID, newURL) {
angular.element(photo).css('background-image','url("' + newURL + '")');
$http.put('/photos/' + photo.id + '.json',{image: newURL}).then(function(resp){
$scope.results[index] = resp.data.photo;
photosAPI.resizeColumns();
$scope.featherEditor.close();
});
},
onClose: function(isDirty) {
showPreview();
},
onError: function(errorObj) {
alert('Oops! There seems to have been a problem with the Image Editor! Please let us know if the issue persists!');
console.log('APIErrorCode: ' + errorObj.code);
console.log('APIErrorMessage: ' + errorObj.message);
console.log('APIErrorArgs: ' + errorObj.args);
showPreview();
}
});
} else {
$scope.featherEditor.launch({
image: ImgID,
url: ImgSrc
});
}
function launchEditor(id, src) {
$scope.featherEditor.launch({
image: id,
url: src
});
return false;
};
function showPreview() {
$scope.editorOpen = false;
angular.element('#close').show()
};
function hidePreview() {
$scope.editorOpen = true;
angular.element('#close').hide()
};
};
私の見解では、モーダルにある次の div があります。
<div id="view_photo">
<div ng-show="!editorOpen">
<div class="photo-preview" id="{{'image-' + results[currentIndex].id}}" ng-style="{'background-image': 'url(' + results[currentIndex].original_image_url + ')'}"></div>
<div class="photo-controls">
<div class="btn btn-default pull-left" style="margin-right:5px;" ng-click="editPhoto(results[currentIndex], '<%= ENV['ADOBE_CLIENT_ID'] %>', currentIndex)">
<i class="fa fa-magic"></i> Edit
</div>
</div>
</div>
</div>