3

私がする必要があるのは、パスを設定した後、json ファイルをダウンロードしてプロバイダーにOCategories割り当てることだけです。PCategoryただし、$http存在しないというエラーが表示されます。プロバイダーに挿入してsetPath関数内にダウンロードするにはどうすればよいですか?

var app = angular.module('NSApp',
    [
        'ui.bootstrap', 
        'MDItem', 
        'MDUser', 
        'MDNotification',
        'MDUpload'
    ]
);


app.config(function(PCategoriesProvider)
{
    PCategoriesProvider.setPath('data/csv/categories.json');
});

MDItem/プロバイダー/category.js

angular.module('MDItem').provider('PCategories',function(){
var OCategories; 
var OPath; 

return{
    setPath: function(d){
        OPath = d; 
        console.log('Path is set. Trying to download categories.');
        OCategories = $http.get(oPath);       

    },

    $get : function() {
        return {
            categories : OCategories
        }
    }

}

});

4

4 に答える 4

12

サービス インスタンスは、まだ構成されていないため、構成関数またはプロバイダーに挿入することはできません。プロバイダーは、特定のサービスが挿入される前に構成するために存在します。つまり、特定のサービスに対応するプロバイダーが常に存在します。明確にするために、$locationを使用してサービスを構成する小さな例を次に示し$locationProviderます。

angular.module('myModule').config(function ($locationProvider) {
  $locationProvider.html5Mode(true);
});

ここで起こることは$location、html5mode を使用するようにサービスを構成することです。が提供するインターフェースを使用してこれを行います$locationProvider。が実行された時点config()では、まだ利用可能なサービス インスタンスはありませんが、インスタンス化される前に任意のサービスを構成する機会があります。

後で実行時に (最初の瞬間はrun()関数です)、サービスを注入できます。サービスを注入するときに得られるものは、そのプロバイダー$get()メソッドが返すものです。つまり、各プロバイダーには$get()関数が必要であり、そうしない$injectorとエラーがスローされます。

しかし、プロバイダーを構築せずにカスタム サービスを作成するとどうなるでしょうか。次のようなものです:

angular.module('myModule').factory('myService', function () {
  ...
});

angularが自動的に行うため、気にする必要はありません。任意の種類のサービスを登録するたびに (プロバイダーでない場合を除く)、angular は$get()メソッドを使用してプロバイダーをセットアップするため、$injector後でインスタンス化できます。

それで、あなたの問題を解決する方法。$http実際に構成フレーズにいるときにサービスを使用して非同期呼び出しを行う方法は? 答え: できません。

できることは、$httpサービスがインスタンス化されたらすぐに呼び出しを実行することです。サービスがインスタンス化された時点で、(いつものように) 他のサービスを注入できるからです。したがって、実際には次のようにします。

angular.module('myModule').provider('custom', function (otherProvider, otherProvider2) {
  // some configuration stuff and interfaces for the outside world

  return {
    $get: function ($http, injectable2, injectable3) {
       $http.get(/*...*/);
    }
  };
});

$httpこれで、カスタム プロバイダーは依存関係を持つサービス インスタンスを返します。サービスが注入されると、そのすべての依存関係も注入されます。つまり、サービス$getにアクセスでき$httpます。次に、必要な電話をかけるだけです。

この呼び出しができるだけ早く呼び出されるようにするには、カスタム サービスrun()を次のようにフレーズに挿入する必要があります。

angular.module('myModule').run(function (custom, injectable2) {
  /* custom gets instantiated, so its $http call gets invoked */
});

これで物事が明確になることを願っています。

于 2013-09-13T20:21:17.957 に答える
3

angular ではすべてのサービスがシングルトンであるため、変数を $http promise でファクトリに格納するだけです。そして、起動時にファクトリが呼び出されると、json がダウンロードされます。

その後、データを更新するメソッドをファクトリに公開することもできます。

これがあなたの質問に対する正確な答えではないことは承知していますが、その方法を共有したいと思います。

angular.module('MDItem').factory('PCategories', function ($http, PCategoriesPath) {
  var service = {
    categories: [],
    get: function () {
      if (angular.isUndefined(PCategoriesPath)) {
        throw new Error('PCategoriesPath must be set to get items');
      }
      $http.get(PCategoriesPath).then(function (response) {
        service.categories = response.data;
      });
    }
  };

  // Get the categories at startup / or if you like do it later.
  service.get();

  return service;
});


// Then make sure that PCategoriesPath is created at startup by using const
angular.module('MDItem').const('PCategoriesPath', 'data/csv/categories.json');

angular.module('app').controller('myCtrl', function ($scope, PCategories) {
  $scope.categories = PCategories.categories;

  // And optionally, use a watch if you would like to do something if the categories are updated via PCategories.get()
  $scope.$watch('categories', function (newCategories) {
    console.log('Look maa, new categories');
  }, true); // Notice the true, which makes angular work when watching an array
})
于 2013-09-13T18:41:58.920 に答える
2

これはインジェクターによって呼び出される関数であるため、関数 $get に $http を注入する必要があります。

ただし、カテゴリをダウンロードするには、 promisesを使用する方がよいでしょう:

angular.module('MDItem').provider('PCategories',function(){
var OCategories; 
var OPath; 

return{
    setPath: function(d){
        OPath = d; 
        console.log('Path is set');    
    },

    $get : function($http) {
        return {
            fetch: function () {
                var deferred = $q.defer();
                $http.get(oPath).then(function (value) {
                    deferred.resolve(value);
                }
                return deferred.promise;
            }
        }
    }

}
});
于 2013-09-13T18:14:23.890 に答える