5

W mojej aplikacji mam 2 prawie identyczne kontrolery. Wiele funkcji jest takich samych, więc chciałbym je prototypować. Jest to kontroler # 1:Jak zrobić prototyp z 2 identycznych kontrolerów w angularjs?

c2gcontroller.js

angular.module('c2gyoApp') 
    .controller('C2gCtrl', function($scope) { 
    // some unique stuff 
    $scope.feeDay = 59; 
    ... 
    // the identical functions 
    $scope.getMinutes = function(minutes) { 
     var duration = moment.duration(minutes, 'm'); 
     return duration.minutes(); 
    }; 
    ... 
    }); 

i kontroler # 2:

c2gbcontroller.js

angular.module('c2gyoApp') 
    .controller('C2gbCtrl', function($scope) { 
    // some unique stuff 
    $scope.feeDay = 89; 
    ... 
    // the identical functions 
    $scope.getMinutes = function(minutes) { 
     var duration = moment.duration(minutes, 'm'); 
     return duration.minutes(); 
    }; 
    ... 
    }); 

Próbowałem oddanie do $scope.getMinutes fabryka:

smfactory.js

angular.module('c2gyoApp') 
    .factory('smfactory', function() { 
    return { 
     getHours: function(minutes) { 
     var duration = moment.duration(minutes, 'm'); 
     return Math.ceil(duration.asHours() % 24); 
     } 
    }; 
    }); 

Mam wstrzykiwany smfactory do c2gcontroller.js

c2gcontroller.js (próba # 1)

angular.module('c2gyoApp') 
    .controller('C2gCtrl', function($scope, smfactory) { 
    ... 
    // the identical functions 
    $scope.getHours = smfactory.getHours(minutes); 
    ... 
    }); 

Daje to błąd, który minuty nie są zdefiniowane

line 33 col 42 'minutes' is not defined. 

Tak próbowałem:

c2gcontroller.js (próba # 2)

angular.module('c2gyoApp') 
    .controller('C2gCtrl', function($scope, smfactory) { 
    ... 
    // the identical functions 
    $scope.getMinutes = function(minutes) { 
     return smfactory.getHours(minutes); 
    }; 
    ... 
    }); 

który nie daje błąd, ale moja aplikacja nie przestanie odpowiadać. Zasadniczo $scope.getMinutes nic nie zwraca teraz.

Wiele czytałem i oglądałem na temat usług AngularJS, fabryk, dostawców, ale nie wiem, dokąd się udać. Jaki byłby właściwy sposób na prototypowanie c2gcontroller.js i c2gbcontroller.js?

Odpowiedz

2

Jak o pseudo dziedziczenia z angular.extend

/* define a "base" controller with shared functionality */ 
.controller('baseCtrl', ['$scope', .. 
    function($scope, ...) { 

    $scope.getMinutes = function(minutes) { 
    var duration = moment.duration(minutes, 'm'); 
    return duration.minutes(); 
    }; 


.controller('C2gCtrl', ['$controller', '$scope', ... 
    function($controller, $scope, ...) { 

    // copies the functionality from baseCtrl to this controller 
    angular.extend(this, $controller('baseCtrl', {$scope: $scope})); 

    // some unique stuff 
    $scope.feeDay = 59; 

}) 

.controller('C2gbCtrl', ['$controller', '$scope', ... 
    function($controller, $scope, ...) { 

    // copies the functionality from baseCtrl to this controller 
    angular.extend(this, $controller('baseCtrl', {$scope: $scope})) 

    // some unique stuff 
    $scope.feeDay = 89; 
}) 
3

to jest, gdy przy użyciu kombinacji grozy JavaScript i składnia controller as naprawdę przydaje.

Jeśli ciągnąć się do typowych funkcji zwykłego starego obiektu:

var commonStuff = { 
    getHours: function(minutes) { 
     var duration = moment.duration(minutes, 'm'); 
     return Math.ceil(duration.asHours() % 24); 
    } 
}; 

Następnie jeśli byłaby nasz kontroler będzie normalny obiekt JS, możemy poszerzyć go o wstawek jeden z dwóch sposobów. Bezpośrednio na samym obiekcie lub poprzez prototyp.

//Using the instance 
function MyCtrl(){ 
    var vm = this; 

    angular.extend(vm, commonStuff); 

    //Other stuff 
} 

//Or via the prototype 
function MyCtrl(){ 
    var vm = this; 
} 

//Controller specific 
MyCtrl.prototype = { 

}; 

angular.extend(MyCtrl.prototype, commonStuff); 

Największą różnicą jest to, że teraz można tylko odwoływać się do kontrolera bezpośrednio poprzez wykorzystanie składni controller as.

<div ng-controller="myCtrl as ctrl"> 
    <a href="" ng-click="ctrl.getHours(120)">Get Hours</a> 
</div> 
+0

Dziękuję bardzo za głęboką odpowiedź!Zdecydowałem się na odpowiedź user2264997, ponieważ nie łamie schematu nazewnictwa Yeomana. – mles

Powiązane problemy