简体   繁体   中英

Angular.js Controller is Loading after the view

Here I'm trying to return the url of each id I receive, but the url is generated asynchronously, as a result its taking time to get generated and I'm unable to put it into the view. How can I make it wait till the data is fetced from PouchDB and Url is generated

controller

    $scope.getColour = function(id) {
        var texture_array = [];
        texture_array = photoList.data.economy.concat(photoList.data.luxury, photoList.data.premium);
        var db = PouchDB('new_test4');
        var obj = {};
        var array = [];
        var i;
        // console.log(texture_array.length)
        for (i = 0; i < texture_array.length; i++) {
            //var id = texture_array[i].image_url;
            if (texture_array[i].image_url == id) {
                db.getAttachment(id, id, function(err, blob_buffer) {
                    if (err) {
                        return console.log(err);
                    } else {
                        var url = URL.createObjectURL(blob_buffer);
                        console.log(url);
                        return url;
                    }
                });
            }

        }

    };

html

<div class="item" ng-repeat="photoOuterObj in remainingEconomyColour " ng-class=" $index? '' : 'active'">
    <div class="row" ng-repeat="photoInnerObj in photoOuterObj">
        <div class="premium-carousel-image">
            <a class="color-image"> <img src="{{getColour(photoInnerObj.image_url)}}" alt="Image" /></a>
            <div class="ambience-button">
            </div>
        </div>
    </div>
</div>

Convert the getColor function to return a promise:

$scope.getColourPromise = function(id) {
    var texture_array = [];
    texture_array = photoList.data.economy.concat(photoList.data.luxury, photoList.data.premium);
    var db = PouchDB('new_test4');
    var obj = {};
    var array = [];
    var i;
     //Create deferred object
    var defer = $q.defer();
    // console.log(texture_array.length)
    for (i = 0; i < texture_array.length; i++) {
        //var id = texture_array[i].image_url;
        if (texture_array[i].image_url == id) {
            db.getAttachment(id, id, function handler(err, blob_buffer) {
                if (err) {
                    //return console.log(err);
                    //reject on error
                    defer.reject("db ERROR "+err);
                } else {
                    var url = URL.createObjectURL(blob_buffer);
                    console.log(url);
                    //resolve with url;
                    defer.resolve(url);
                }
            });
        }
    }
    //return promise
    return defer.promise;
};

Because the getAttachment method executes the getHandler function asynchronously after the getColour function completes, it can't return a value, but it can resolve a defer object.

Use ng-init to fetch the url and attach it the ng-repeat iterator object:

<div class="row" ng-repeat="innerObj in photoOuterObj">
    <!-- use ng-init to do the fetch -->
    <div ng-init="innerObj.urlObj = fetchURL(innerObj)">
        <a class="color-image"> <img ng-src="{{innerObj.urlObj.url}}" alt="Image" /></a>
        <div class="ambience-button">
        </div>
    </div>
</div>

The fetch function:

$scope.fetchURL = function(itemObj) {
    var urlObj = {};
    urlObj.url = "default.jpg";
    var promise = $scope.getColourPromise(itemObj.image_url);
    promise.then(function (url) {
        urlObj.url = url;
    });
    return urlObj;
});

The fetch initially returns an object with the url property set to a default value. When the promise resolves, it will be set to the fetched value. The watcher created the double curly bracket {{ }} expression will update the DOM.

Avoid using asynchronous functions in an interpolation {{ }} because they get called multiple times every digest cycle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM