Как включать/вводить функции, которые используют $scope в контроллер в angularjs?

Я пытаюсь включить библиотеку функций, содержащуюся в factory, в контроллер. Подобно вопросам вроде этого: Создание общих функций контроллера

Мой главный контроллер выглядит следующим образом:

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 файле я создал файл factory groceryInterface. Я ввел этот factory в контроллер выше.

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

Но в моей консоли я продолжаю получать ReferenceError: $scope is not defined at Object.factory.addToList и т.д.. Очевидно, я предполагаю, что это связано с тем, что я использую $scope в своих функциях в factory. Как это разрешить? Я замечаю, что во многих других примерах, на которые я смотрел, никто никогда не использовал $scope в своих внешних factory функциях. Я попытался вставить $scope в качестве параметра в свой factory, но этот простой не работал. (например, recipeApp.factory('groceryInterface', function(){)

Любая помощь действительно оценена!

Ответ 1

Ваш factory не может получить доступ к вашему $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();
    }
});

В качестве альтернативы вы можете попробовать использовать более объектно-ориентированный подход:

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

Ответ 2

Вы не можете использовать $scope в factory, поскольку он не определен. Вместо этого в ваших функциях factory изменяются свойства объекта, возвращаемого factory, например.

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. 

Ответ 3

Это не точный ответ на этот вопрос, но у меня были аналогичные проблемы, которые я решил, просто передав $scope в качестве аргумента функции в моем factory. Таким образом, это не будет нормальная $scope, а $scope в момент вызова функции в factory.

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