我如何添加一些小的实用function到我的AngularJS应用程序?
我想添加一些实用function到我的AngularJS应用程序。 例如:
$scope.isNotString = function (str) { return (typeof str !== "string"); }
最好的方法来做到这一点,将它们添加为服务? 从我读过的,我可以做到这一点,但是我想在我的HTML页面中使用这些,所以如果他们在服务中仍然有可能? 例如,我可以使用以下内容:
<button data-ng-click="doSomething()" data-ng-disabled="isNotString(abc)">Do Something </button>
有人可以给我一个如何添加这些的例子。 我应该创build一个服务还是有其他的方式来做到这一点。 最重要的是我希望这些实用function在一个文件中,而不是与主要设置的另一部分相结合。
我明白有几个解决scheme,但没有一个是如此清晰。
解决scheme1 – 由城市提出
$scope.doSomething = ServiceName.functionName;
这里的问题是我有20个function和10个控制器。 如果我这样做,这意味着要添加大量的代码到每个控制器。
解决scheme2 – 由我提出
var factory = { Setup: function ($scope) { $scope.isNotString = function (str) { return (typeof str !== "string"); }
这样做的缺点是,在每个控制器启动时,我将对每个通过$ scope的服务进行一次或多次这样的Setup调用。
解决scheme3 – 由城市提出
城市提出的通用服务解决scheme看起来不错。 这是我的主要设置:
var app = angular .module('app', ['ngAnimate', 'ui.router', 'admin', 'home', 'questions', 'ngResource', 'LocalStorageModule']) .config(['$locationProvider', '$sceProvider', '$stateProvider', function ($locationProvider, $sceProvider, $stateProvider) { $sceProvider.enabled(false); $locationProvider.html5Mode(true);
我应该添加通用服务到这个,我怎么能做到这一点?
编辑7/1/15:
我很久以前写了这个答案,一直没有跟上这个答案,但似乎这个答案还是比较stream行,所以我想指出一点@nicolas使得以下是好的。 首先,注入$ rootScope并附加助手将使您不必为每个控制器添加它们。 另外 – 我同意,如果你添加应该被认为是angular度服务或filter,他们应该采用这种方式的代码。
而且,从目前的版本1.4.2开始,Angular公开了一个“Provider”API,它被允许注入到configuration块中。 查看更多资源:
https://docs.angularjs.org/guide/module#module-loading-dependencies
AngularJSdependency injectionmodule.config中的值
我不认为我会更新下面的实际代码块,因为我现在没有真正积极使用Angular,而且我也不想冒一个新的答案而不自觉地确实符合新的最好的实践。 如果别人觉得它,尽一切办法去做。
编辑2/3/14:
在思考这个问题并阅读其他一些答案后,我实际上认为我更喜欢@Brent Washburne和@Amogh Talpallikar提出的方法的一个变种。 特别是如果你正在寻找像isNotString()或类似的工具。 其中一个明显的优点是,你可以在你的angular码之外重新使用它们,你可以在你的configuration函数中使用它们(你不能用服务来做)。
这就是说,如果你正在寻找一种通用的方式来重新使用正确的服务,我认为旧的答案仍然是一个很好的答案。
我现在要做的是:
app.js:
var MyNamespace = MyNamespace || {}; MyNamespace.helpers = { isNotString: function(str) { return (typeof str !== "string"); } }; angular.module('app', ['app.controllers', 'app.services']). config(['$routeProvider', function($routeProvider) { // Routing stuff here... }]);
controller.js:
angular.module('app.controllers', []). controller('firstCtrl', ['$scope', function($scope) { $scope.helpers = MyNamespace.helpers; });
然后在你的部分你可以使用:
<button data-ng-click="console.log(helpers.isNotString('this is a string'))">Log String Test</button>
老答案如下:
将它们包括为服务可能是最好的。 如果你打算在多个控制器上重复使用它们,包括它们作为一项服务将使你不必重复代码。
如果你想在你的html部分中使用服务函数,那么你应该将它们添加到该控制器的作用域中:
$scope.doSomething = ServiceName.functionName;
然后在你的部分你可以使用:
<button data-ng-click="doSomething()">Do Something</button>
以下是你可以保持这种有组织的方式,免于太多的麻烦:
将控制器,服务和路由代码/configuration分离为三个文件:controllers.js,services.js和app.js. 顶层模块是“app”,它具有app.controllers和app.services作为依赖关系。 然后,app.controllers和app.services可以在自己的文件中声明为模块。 这个组织结构只是从angular种子 :
app.js:
angular.module('app', ['app.controllers', 'app.services']). config(['$routeProvider', function($routeProvider) { // Routing stuff here... }]);
services.js:
/* Generic Services */ angular.module('app.services', []) .factory("genericServices", function() { return { doSomething: function() { //Do something here }, doSomethingElse: function() { //Do something else here } });
controller.js:
angular.module('app.controllers', []). controller('firstCtrl', ['$scope', 'genericServices', function($scope, genericServices) { $scope.genericServices = genericServices; });
然后在你的部分你可以使用:
<button data-ng-click="genericServices.doSomething()">Do Something</button> <button data-ng-click="genericServices.doSomethingElse()">Do Something Else</button>
这样,您只需向每个控制器添加一行代码,并且可以访问任何可以访问该范围的服务function。
在这个老线上,我想强调一下
1°)实用function可能(应该?)通过module.run添加到rootcope。 为此,不需要为特定的根级别控制器设置实例。
angular.module('myApp').run(function($rootScope){ $rootScope.isNotString = function(str) { return (typeof str !== "string"); } });
2°)如果你把你的代码组织成单独的模块,你应该使用angular度服务或工厂 ,然后将它们注入到传递给运行块的函数中,如下所示:
angular.module('myApp').factory('myHelperMethods', function(){ return { isNotString: function(str) { return (typeof str !== 'string'); } } }); angular.module('myApp').run(function($rootScope, myHelperMethods){ $rootScope.helpers = myHelperMethods; });
3°)我的理解是,在视图中,对于大多数情况下,您需要这些帮助函数来对显示的string应用某种格式。 你最后需要的是使用angular度filter
如果你已经将一些低级别的帮助器方法构造到angular度服务或工厂中,只需将它们注入到你的filter构造函数中:
angular.module('myApp').filter('myFilter', function(myHelperMethods){ return function(aString){ if (myHelperMethods.isNotString(aString)){ return } else{ // something else } } );
在你看来:
{{ aString | myFilter }}
我是否正确理解您只是想定义一些实用方法并使其在模板中可用?
您不必将其添加到每个控制器。 只需为所有的实用程序方法定义一个控制器,并将该控制器附加到<html>或<body>(使用ngController指令)即可。 您在<html>(意思是任何地方,句点)或<body>(除了<head>之外的任何地方)任何地方附加的任何其他控制器将inheritance该$ scope,并且将有权访问这些方法。
添加实用程序function的最简单方法是将其保留在全局级别:
function myUtilityFunction(x) { return "do something with "+x; }
然后,添加实用程序函数(到控制器)的最简单方法是将其分配给$scope
,如下所示:
$scope.doSomething = myUtilityFunction;
那么你可以这样调用它:
{{ doSomething(x) }}
或者像这样:
ng-click="doSomething(x)"
编辑:
原来的问题是,如果添加效用函数的最佳方式是通过服务。 我说不,如果这个函数足够简单的isNotString()
比如OP所提供的isNotString()
例子)。
编写服务的好处是为了testing的目的,用另一个(通过注入)replace它。 采取了极端的,你需要注入每一个实用function到你的控制器?
文档说只是在控制器中定义行为(如$scope.double
): http : $scope.double
这是一个简单,简洁,易于理解的方法。
首先,在你的js中添加一个服务。
app.factory('Helpers', [ function() { // Helper service body var o = { Helpers: [] }; // Dummy function with parameter being passed o.getFooBar = function(para) { var valueIneed = para + " " + "World!"; return valueIneed; }; // Other helper functions can be added here ... // And we return the helper object ... return o; }]);
然后,在你的控制器中,注入你的帮助对象,并使用任何可用的函数,如下所示:
app.controller('MainCtrl', [ '$scope', 'Helpers', function($scope, Helpers){ $scope.sayIt = Helpers.getFooBar("Hello"); console.log($scope.sayIt); }]);
为什么不使用控制器inheritance,在HeaderCtrl范围内定义的所有方法/属性都可以在控制器内的ng-view中访问。 $ scope.servHelper可以在你所有的控制器中访问。
angular.module('fnetApp').controller('HeaderCtrl', function ($scope, MyHelperService) { $scope.servHelper = MyHelperService; }); <div ng-controller="HeaderCtrl"> <div ng-view=""></div> </div>
您也可以使用固定的服务。 定义常量调用之外的函数也允许它recursion。
function doSomething( a, b ) { return a + b; }; angular.module('moduleName',[]) // Define .constant('$doSomething', doSomething) // Usage .controller( 'SomeController', function( $doSomething ) { $scope.added = $doSomething( 100, 200 ); }) ;