12

私は、ファクトリで保持されている関数のライブラリをコントローラに組み込もうとしています。このような質問に似て : Creating common controller functions

マイメインコントローラは次のようになります。そして、

recipeApp.controller('recipeController', function ($scope, groceryInterface, ...){ 

$scope.groceryList = []; 
// ...etc...  

/* trying to retrieve the functions here */ 
$scope.groceryFunc = groceryInterface; // would call ng-click="groceryFunc.addToList()" in main view 
    /* Also tried this: 
    $scope.addToList = groceryInterface.addToList(); 
    $scope.clearList = groceryInterface.clearList(); 
    $scope.add = groceryInterface.add(); 
    $scope.addUp = groceryInterface.addUp(); */ 
} 

、別の.jsファイルでは、私は工場groceryInterfaceを作成しました。私はこの工場を上記のコントローラに注入しました。

工場

recipeApp.factory('groceryInterface', function(){ 

     var factory = {}; 

    factory.addToList = function(recipe){ 
     $scope.groceryList.push(recipe); 
        ... etc.... 
    } 

    factory.clearList = function() { 
      var last = $scope.prevIngredients.pop(); 
      .... etc... 
    } 

    factory.add = function() { 
    $scope.ingredientsList[0].amount = $scope.ingredientsList[0].amount + 5; 
    } 

    factory.addUp = function(){ 
     etc... 
    } 

    return factory; 
}); 

しかし、私のコンソールで、私はもちろん、私はこれは私が以内に私の機能で$scopeを使用していたという事実に関係している推測しているなど、ReferenceError: $scope is not defined at Object.factory.addToListを得続けます工場。これをどうやって解決するのですか?私は多くの他の例で見てきましたが、誰も外部ファクトリ関数内で$scopeを使用することはありません。私は私の工場でパラメータとして$scopeを注入しようとしましたが、それはうまく動作しませんでした。 (例:recipeApp.factory('groceryInterface', function(){

本当にありがとうございます。

答えて

25

あなたの工場は同じ範囲にないので、$scopeにアクセスすることはできません。

代わりにこれを試してみてください:

recipeApp.controller('recipeController', function ($scope, groceryInterface) { 

    $scope.addToList = groceryInterface.addToList; 
    $scope.clearList = groceryInterface.clearList; 
    $scope.add  = groceryInterface.add; 
    $scope.addUp  = groceryInterface.addUp; 
} 

recipeApp.factory('groceryInterface', function() { 

    var factory = {}; 

    factory.addToList = function (recipe) { 
     this.groceryList.push(recipe); 
    } 

    factory.clearList = function() { 
     var last = this.prevIngredients.pop(); 
    } 
}); 

また、あなたがより多くのオブジェクト指向のアプローチを使用して試すことができます:それは定義されていないとして、あなたは工場で$scopeを使用することはできません

recipeApp.controller('recipeController', function ($scope, groceryInterface) { 

    $scope.groceryFunc = new groceryInterface($scope); 
} 

recipeApp.factory('groceryInterface', function() { 

    function Factory ($scope) { 

     this.$scope = $scope; 
    } 

    Factory.prototype.addToList = function (recipe) { 
     this.$scope.groceryList.push(recipe); 
    } 

    Factory.prototype.clearList = function() { 
     var last = this.$scope.prevIngredients.pop(); 
    } 

    return Factory; 
}); 
+0

甘い、ありがとう。私はこれを試してみよう! – LazerSharks

+2

@Gnuey - 古いバージョンのIEでは 'bind'が利用できないことに注意してください。これらをサポートする必要があり、最初のメソッドを使いたい場合は、[this MDN polyfill](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#互換性)、またはページにjQueryがある場合は、代わりに['$ $ .proxy'](http://api.jquery.com/jQuery.proxy/)を使用してください。 –

+1

さて、素晴らしい。それは実際には非常に有益な情報です - 私の部長とサイト訪問者は時々何らかの理由で古いIEバージョンを使用します:\代わりに '$ scope.addToList = $ .proxy(groceryInterface.addToList、$ scope)'と書くでしょうか? – LazerSharks

4

。代わりに、ファクトリ関数でファクトリが返すオブジェクトのプロパティを変更します。

factory.addToList = function (recipe) { 
    this.groceryList.push(recipe); 
} 

これらはその後、これは、この質問に対する正確な答えはありませんが、私は、私は単に$スコープを渡すことによって解決同様の問題を持っていたあなたの$scope変数

$scope.addToList = groceryInterface.addToList; 
// ... = groceryInterface.addToList(); would assign to `$scope.addToList` what is returned, instead of the function itself. 
+0

ありがとう、私はこれを試してみましょう! – LazerSharks

+1

'$ scope.addToList = groceryInterface.addToList();'の代わりに '$ scope.addToList = groceryInterface.addToList; 'を読み込むようにあなたの解を編集しました。' addTotList() 'の最後のカッコが、私のデバッグプロセス中に大きな問題が1つありました...自分自身でJavaScriptシンタックスの非常にすっきりした叩きを得ました... – LazerSharks

3

に渡されます私の工場の関数への引数。したがって、通常の$スコープではなく、ファクトリの関数が呼び出された時点での$スコープになります。

app.controller('AppController', function($scope, AppService) { 


    $scope.getList = function(){ 

    $scope.url = '/someurl' 

    // call to service to make rest api call to get data 

    AppService.getList($scope).then(function(res) { 
     // do some stuff 

    }); 
    } 

}); 


app.factory('AppService', function($http, $q){ 
    var AppService = { 

    getList: function($scope){ 
     return $http.get($scope.url).then(function(res){ 
     return res; 
     }); 
    }, 

    } 

    return AppService; 
}); 
+0

DRY AF ..そしてファクトリ関数にパラメータを渡す方法 – HoosierCoder

関連する問題