Domanda

I have two controllers which perform very similar tasks.

What's the appropriate way to remove code duplication?

Initially I tried to move create a template method as an angular service, but it looks like I cannot inject $scope to services.

.controller("TspController", function($scope, $rootScope, $routeParams, $location, ProblemsLoader) {
    $scope.problemType = "tsp";
    var problemId = $routeParams.problemId;

    ProblemsLoader.loadIndex("tsp", function(index) {
        if (problemId) {
            $scope.problems = index;
            ProblemsLoader.loadProblem("tsp", problemId, function(problem) {
                $scope.problem = problem
            });
        } else {
            var firstProblemId = index[0].fileName;
            $location.path("/tsp/" + firstProblemId)
        }
    });
})
.controller("VrpController", function($scope, $rootScope, $http, $routeParams, ProblemsLoader) {
    $scope.problemType = "vrp";
    var problemId = $routeParams.problemId;

    ProblemsLoader.loadIndex("vrp", function(index) {
        if (problemId) {
            $scope.problems = index;
            ProblemsLoader.loadProblem("vrp", problemId, function(problem) {
                $scope.problem = problem
            });
        } else {
            var firstProblemId = index[0].fileName;
            $location.path("/vrp/" + firstProblemId)
        }
    });
});
È stato utile?

Soluzione

Actually, services are a good solution for this use case, and injecting $scope isn't necessary.

When a service exposes an object property, implicit watches are set up on them, so state changes get propogated transparently.

Service:

var problemSvc = function($http) {
    var problemData = {
        problemId: 1,
        problemField: '',
        otherProblemField: ''
    };

    return {
        problem: problemData, // exposing the data as object
        loadProblem: function(problemId) {
            // load logic here
            problemData.problemField = 'load data here';
            problemdata.otherProblemField = 'more data from server or whatever';
        }
    }
}
angular.service('problemSvc', ['$http', problemSvc]);

1-N consuming controllers:

angular.controller('ctrl', ['$scope', 'problemSvc', function($scope, problemSvc) {
    $scope.problem = problemSvc.problem;
}]);

As fields change in your problem service, any controller where the service is injected will be updated automatically

<div>{{problem.problemField}}</div>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top