Angular ng-show not working consistently

时间:2016-02-12 21:57:28

标签: javascript angularjs ng-show angular-digest adobecreativesdk

The Problem

I'm trying to integrate the Adobe Creative SDK into my Angular app. The editor is initialized from a photo viewer modal by clicking a button, which triggers the function below. Once the editor has been initialized, the undefined symbols for architecture x86_64: "ClassName:: FunctionName(ClassName&)", referenced from: _main in lab2-f679eb.o ld: symbol(s) not found for architecture x86_64 callback hides the photo viewer elements and the editor is appended to the modal. This part works great.

In my modal DOM I'm trying to use onReady and ng-show="editorOpen" on the elements I wish to show or hide, depending on whether or not the editor is open. The first time I trigger ng-show="!editorOpen", $scope.editPhoto works as expected. When I close the editor however, ng-show fails to update the DOM. The editor disappears, however the hidden photo viewer elements remain hidden.

I'm no expert on Angular's digest cycle, but from what I've been able to find out from my research, I believe the problem is that the ng-show and hidePreview() functions are being called during a digest cycle, causing showPreview() not to register the change to ng-show.

Once I close the editor and $scope.editorOpen fails to update the DOM, I can still trigger it manually by doing another action within the app that triggers a digest cycle, such as using the left/right arrow keys to try and navigate to the next photo in the viewer modal.

It gets weirder from here though. Once I've closed the editor and manually triggered a digest, everything seems normal. If I re-open the editor a second time, ng-show stops working altogether, even if I try to manually trigger a digest using the method I just described.

Solutions I've Tried

I've tried a number of possible fixes, including every solution offered in this discussion to solve the problem, all of which have failed.

  1. I tried wrapping ng-show and $scope.editorOpen = true in a $scope.editorOpen = false function, since that should trigger a digest. I tried setting the delay to 0ms and 10ms. Both failed.
  2. I created a scoped function $timeout to toggle $scope.toggleEditor and passed that into the Adobe Creative SDK image editor's $scope.editorOpen, onSave, and onReady callbacks, instead of the onClose and showPreview() functions I have in my code below. That also failed.
  3. I tried wrapping my entire hidePreview() function in a $scope.editPhoto function. Also failed.
  4. I tried the more direct approach of manually calling $timeout as well as $scope.$apply() within my $scope.$digest() and showPreview() functions. That typically worked only once before raising a hidePreview() error, and also smells like bad practice.
  5. Finally, getting more desperate, I tried $rootScope:inprog, just to see if it would solve the problem, despite being a terrible practice. Unsurprisingly it also failed just like #4.

The Code

In my controller I have the following function:

if (!$scope.$$phase) $scope.$apply()

In my view I have the following div, which lives in a modal:

$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()
    };
};

0 个答案:

没有答案