5

Nella mia app ho 2 controller quasi identici. Molte funzioni sono le stesse, quindi mi piacerebbe prototiparle. Questo è Controller # 1:Come realizzare un prototipo su 2 controller identici in 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(); 
    }; 
    ... 
    }); 

e Controller # 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(); 
    }; 
    ... 
    }); 

Ho provato a mettere in $scope.getMinutes una fabbrica:

smfactory.js

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

ho iniettato smfactory in c2gcontroller.js

c2gcontroller.js (tentativo # 1)

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

Questo produce un errore che i minuti non sono definiti

line 33 col 42 'minutes' is not defined. 

Così ho provato:

c2gcontroller.js (tentativo # 2)

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

che non cede di un errore, ma la mia app ha fatto diventare non risponde. Fondamentalmente $scope.getMinutes non restituisce nulla ora.

Ho letto e guardato molto sui servizi, le fabbriche, i fornitori di AngularJS, ma non so da dove andare. Quale sarebbe il modo corretto di prototipizzare c2gcontroller.js e c2gbcontroller.js?

risposta

2

Che ne dite di pseudo eredità con 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

Questo è dove utilizzando una combinazione di suggestioni JavaScript, e la sintassi controller as è molto utile.

Se tiriamo le funzioni comuni fuori in un vecchio oggetto pianura:

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

Se poi refactoring nostro controller ad essere un oggetto normale JS, siamo in grado di aumentare con un mixin uno dei due modi. O direttamente sull'oggetto stesso o tramite il prototipo.

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

La più grande differenza è che ora si può solo fare riferimento al comando direttamente attraverso l'uso della sintassi controller as.

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

Grazie mille per la tua profonda risposta!Ho deciso di andare con la risposta dell'utente 2264997 in quanto non infrange lo schema di denominazione di Yeoman. – mles

Problemi correlati