Как включать/вводить функции, которые используют $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;
});