Use asynchronous data when creating a factory

In one of my applications, I want to use $ resource to clear read / write operations, but the url has a prefix that I cannot know until I finish loading the preference document. I don’t know how to clear the factory creation until ajax returns.

This is similar to "Do not initialize the application until some ajax data returns," but all the examples that I could find (using $route.resolve) delay the controller, not the factory.

Here is my ideal jsFiddle .

I think GitHub pull # 3295 can just magically make the violin work higher, but I'm looking for alternatives until it is merged.

My current fix is here , but this leads to multiple instances $resourceand a suggestion resolvefor each route that needs a factory or preference document.

+4
source share
2 answers

Inject Angular Ui Router and reorganize your Doc as a factory provider instead of a factory service

script: http://jsfiddle.net/LongLiveCHIEF/5kSbC/

  • Change your factory to a vendor (still using the method .factory), and your prefs service should be processed with prior permission using ui.router.
  • prefs prefix docs factory ( ), .
  • Doc factory .

$state (ui.router)

.when() ui.router , , . , , ( ). :

https://github.com/NormalGravity/evsvillas.com/blob/master/app/src/app.js.

22-38. ( ), , .

:

+1

, ​​ " Angular".

, $offer .

, ( ):

HTML

<!-- test will be holding the lazy registered value -->
<body ng-app="App" ng-controller="TestController">
   {{test}}
</body>

JS ( )

var App = angular.module('App', []);

// prepare the external reference holder
var provide;

// use a config function to externalize the $provide provider
App.config(function($provide) {
    provide = $provide;
});

// delayed $provide use with a timeout
App.run(function($timeout) {
    // async function with one of the followings
    // - $timeout
    // - $q
    // - $http
    // which actually register the value (could be a factory or what you want)
    // at t+1000ms
    $timeout(function() {
        // here I provide a simple object but you can pass a $resource !
        provide.value('Test', {a:1});
    },1000);
});

// watch the existence of the service
// OR broadcast an event from $rootScope
// OR the way you want to tell the service now exists
App.controller('TestController', function($injector, $scope) {
    var unwatch = $scope.$watch(function() { 
        return $injector.has('Test');
    }, function(has) {
        if(has) {
            $scope.test = $injector.get('Test');
            unwatch();
        }
    });
});

, , async. . , , , , , , .

UPDATE

" " , , :

JS

var App = angular.module('App', []);

App.factory('MyLazyFactory', function($timeout) {
    // here I delay with $timeout but
    // it can be delayed with $http !
    // ($timeout returns a promise, resolved with the inner returned value)
    return $timeout(function() {
        // here I return an object but
        // it can be a $resource !
        return {a:1};
    },1000);
});

App.controller('TestController', function(MyLazyFactory, $scope) {
    MyLazyFactory.then(function(myFactory) {
        // here I really get the value returned by the timeout callback
        $scope.test = myFactory;
    });
});

, .

UPDATE ( $resource , )

, , , jsFiddle.

JS

angular.module('myApp',["ngResource"])

.service("LazyPrefs", [ "$http", function($http) {
    return $http.post("/echo/json/", "json={\"prefix\":\"/echo/json/test\"}")
        .then(function(response) { return response.data; });
}])

.factory("LazyDoc", [ "$resource", "LazyPrefs", function($resource, LazyPrefs) {
    return LazyPrefs.then(function(Prefs) {
        console.log("Using " + Prefs.prefix + " as prefix");
        return $resource(Prefs.prefix + "/:docId", { docId:"@id" });
    });
}])

.controller("MainCtrl", [ "$scope", "$http", "LazyDoc", function($scope, $http, LazyDoc) {
    LazyDoc.then(function(Doc) {
        $scope.doc = new Doc({ name: "Steve", photo: "profile.jpg" });
    });
}]);
-1

Source: https://habr.com/ru/post/1527134/


All Articles