12

Bir fabrikada tutulan işlev kitaplığını bir denetleyiciye dahil etmeye çalışıyorum. Bu gibi sorulara benzer : şöyle Creating common controller functions

Benim ana kontrolör:

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

Sonra, başka bir .js dosyasında, ben fabrika groceryInterface oluşturduk. Bu fabrikayı yukarıdaki kontrolöre enjekte ettim.

Fabrika

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

Ama konsolda ben Açıkçası ben bu ben içinde benim fonksiyonları $scope kullanıyorum gerçeği ile ilgisi var tahmin ediyorum, vbReferenceError: $scope is not defined at Object.factory.addToList almaya devam fabrika. Bunu nasıl çözebilirim? Baktığım diğer birçok örnekte, hiç kimse $scope'u harici fabrika işlevlerinde kullanmıyor. Fabrikamda $scope parametresini parametre olarak denedim, ancak bu düzlük işe yaramadı. (ör. recipeApp.factory('groceryInterface', function(){)

Herhangi bir yardım gerçekten takdir edilmektedir!

cevap

25

Fabrikanız, aynı kapsamda olmadığından $scope ürününüze erişemiyor.

yerine bu deneyin:

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

Alternatif olarak, bir daha nesne yönelimli yaklaşım kullanarak deneyebilirsiniz: o tanımlı değil gibi bir fabrikada $scope kullanamaz

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

Tatlı, teşekkürler. Bunu deneyeceğim! – LazerSharks

+2

@Gnuey - 'bind''in IE'nin eski sürümlerinde mevcut olmadığını unutmayın. Bunları desteklemek ve ilk yöntemi kullanmak istiyorsanız, ya [bu MDN polyfill] kullanın (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind# Uyumluluk) veya - jQuery sayfanız varsa - bunun yerine ['$ .proxy'] (http://api.jquery.com/jQuery.proxy/) kullanın. –

+1

Tamam, harika. Bu aslında son derece yararlı bilgiler - benim dept baş ve site ziyaretçileri bazı nedenlerle zaman zaman eski IE sürümleri kullanıyor: \ Bunun yerine $ scope.addToList = $ .proxy (bakeryInterface.addToList, $ scope) 'yazabilir miyim? – LazerSharks

4

. Bunun yerine, fabrika işlevlerinizde fabrika geri dönen nesnenin özelliklerini değiştirir, örn.

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

bu

sonra aktarılır alacak senin $scope değişken

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

Teşekkürler, bunu deneyeceğim! '$ Scope.addToList = groceryInterface.addToList', okur; bunun yerine '$ scope.addToList = groceryInterface.addToList() ait olacak şekilde – LazerSharks

+1

Ben senin çözüm düzenlenmiş' ı keşfetti addTotList 'sonunda parantez()' hata ayıklama işlemi sırasında büyük bir sorun oldu ... kendimi oldukça güzel bir javascript sözdizimi tokatını aldım ... – LazerSharks

3

Bu soru için kesin cevap değil, ama ben olarak basitçe geçirerek $ kapsamı çözülebilir benzer sorunlar vardı fabrikamdaki bir işleve bir argüman. Yani normal $ kapsamı olmayacak, ancak fabrikadaki işlev çağrıldığında $ kapsamı.

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 .. ve fabrika fonksiyonlarına paramizi geçirmenin bir yolu – HoosierCoder

İlgili konular