I am trying to include a library of functions, held in a factory, into a controller. Similar to questions like this: Creating common controller functions

My main controller looks like this:

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

Then, in another .js file, I have created the factory groceryInterface. I've injected this factory into the controller above.

Factory

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

But in my console I keep getting ReferenceError: $scope is not defined at Object.factory.addToList, etc. Obviously I'm guessing this has to do with the fact that I'm using $scope in my functions within the factory. How do I resolve this? I notice that in many other examples I've looked at, nobody ever uses $scope within their external factory functions. I've tried injecting $scope as a parameter in my factory, but that plain out did not work. (e.g. recipeApp.factory('groceryInterface', function(){ )

Any help is truly appreciated!

有帮助吗?

解决方案

Your factory can't access your $scope, since it's not in the same scope.

Try this instead:

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

Alternatively, you can try using a more object oriented approach:

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

其他提示

You cannot use $scope in a factory as it is not defined. Instead, in your factory functions change the properties of the object the factory is returning, e.g.

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

these will then get passed on to your $scope variable

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

This isn't the exact answer for this question, but I had a similar issues that I solved by simply passing $scope as an argument to a function in my factory. So it won't be the normal $scope, but $scope at the time the function in the factory is called.

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;
});
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top