AngularJS1 Factory模式实现报错求助:MathService未返回值
解决AngularJS 1.x Factory模式报错:Provider 'MathService' must return a value from $get factory method
嘿,我一眼就揪出了几个导致报错和功能异常的问题,咱们一个个捋清楚:
核心报错原因:Factory未返回有效实例
你的MathService工厂里定义了techlabs函数,但没有执行这个函数并返回它的结果。AngularJS的factory要求你传入的函数必须返回一个对象/函数作为服务实例,现在你只定义了techlabs却没调用,相当于底层的$get方法没有返回值,直接触发了那个报错。
其他功能问题
除了报错,代码还有几个逻辑和使用上的坑:
- 控制器调用方式错误:你在控制器里直接用
$scope.isPrime(),但根本没把MathService的方法挂载到$scope上,也没直接调用MathService的方法,肯定会报undefined。 - isPrime逻辑错误:
return true写在了for循环内部,导致只要第一个除数不整除就直接返回true,不会检查后续的数(比如15会被误判为质数,因为15%2!=0就直接return true了)。 - 日志描述错误:
isCubeEvenNo里的$log日志写反了,判断cube是偶数的时候,日志却写“is not a even number”,逻辑完全不符。
修复后的完整代码
<html ng-app="Swabhav.ServiceApp"> <head> <title> Factory Pattern </title> <script src="angular.js"></script> <script> var oneModule = angular.module("Swabhav.ServiceApp", []); // 修复Factory:执行techlabs函数并返回结果 oneModule.factory("MathService", ["$log", function($log){ $log.log("Inside Math Service"); var techlabs = function(){ var obj = {}; // 修复isPrime逻辑:把return true移到循环结束后,添加边界处理 obj.isPrime = function(number){ if(number <= 1) return false; for(var index=2; index<=Math.sqrt(number); index++){ if(number%index == 0){ console.log(number + " Is not a prime number"); $log.log("inside $log - " + number + " is not a prime"); return false; } } console.log(number + " Is a prime number"); $log.log("inside $log - " + number + " is a prime"); return true; } // 修复日志描述,统一逻辑 obj.isCubeEvenNo = function(number){ var cube = number * number * number; var isEven = cube % 2 == 0; if(isEven){ console.log("Cube of " + number + " is even"); $log.log("inside $log - Cube of " + number + " is even"); } else { console.log("Cube of " + number + " is odd"); $log.log("inside $log - Cube of " + number + " is odd"); } return isEven; } return obj; }; // 关键:执行techlabs函数,返回服务实例 return techlabs(); }]); // 修复控制器:正确调用MathService的方法,同时支持页面交互 oneModule.controller("FirstController", ["$scope","MathService",function($scope, MathService){ // 直接调用测试 console.log(MathService.isPrime(10)); console.log(MathService.isPrime(13)); // 挂载到$scope供页面使用 $scope.checkPrime = function(num){ return MathService.isPrime(num); } }]); oneModule.controller("SecondController", ["$scope","MathService",function($scope, MathService){ // 直接调用测试 console.log(MathService.isCubeEvenNo(2)); console.log(MathService.isCubeEvenNo(7)); // 挂载到$scope供页面使用 $scope.checkCubeEven = function(num){ return MathService.isCubeEvenNo(num); } }]); </script> </head> <body> <div ng-controller="FirstController"> <h3>检查质数</h3> <input type="text" ng-model="primeNum" placeholder="输入数字"> <button ng-click="checkPrime(primeNum)">检查</button> <p>结果:{{checkPrime(primeNum) ? '是质数' : '不是质数'}}</p> </div> <div ng-controller="SecondController"> <h3>检查立方是否为偶数</h3> <input type="text" ng-model="cubeNum" placeholder="输入数字"> <button ng-click="checkCubeEven(cubeNum)">检查</button> <p>结果:{{checkCubeEven(cubeNum) ? '立方是偶数' : '立方是奇数'}}</p> </div> </body> </html>
修复点总结
- 在MathService工厂最后添加
return techlabs();,确保返回服务实例,解决核心报错。 - 调整isPrime函数的return true位置到循环外,添加小于2的数非质数的边界处理,同时优化循环到平方根提升效率。
- 修复isCubeEvenNo的日志描述,让逻辑和日志保持一致。
- 控制器里正确调用MathService的方法,同时添加了挂载到$scope的代码,支持页面交互使用。
内容的提问来源于stack exchange,提问作者java_jazz
相关产品推荐
相关产品推荐

