如何向我的 AngularJS 应用程序添加一些小的实用函数? [英] How can I add some small utility functions to my AngularJS application?

查看:28
本文介绍了如何向我的 AngularJS 应用程序添加一些小的实用函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想向我的 AngularJS 应用程序添加一些实用函数.例如:

I would like to add some utility functions to my AngularJS application. For example:

$scope.isNotString = function (str) {
    return (typeof str !== "string");
}

这是将它们添加为服务的最佳方法吗?从我所读到的,我可以做到这个但是我想在我的 HTML 页面中使用这些,所以如果他们在服务?例如,我可以使用以下内容:

Is the best way to do this to add them as a service? From what I have read I can do this but then I would like to use these in my HTML pages so is it still possible if they are in a service? For example can I use the following:

 <button data-ng-click="doSomething()"
         data-ng-disabled="isNotString(abc)">Do Something
 </button>

谁能举个例子告诉我如何添加这些.我应该创建一个服务吗或者有其他方法可以做到这一点.最重要的是我想要这些实用程序功能在一个文件中,而不是与主要设置的另一部分结合.

Can someone give me an example of how I could add these. Should I create a service or is there some other way of doing it. Most important I would like these utility functions in a file and not combined with another part of the main set up.

我知道有一些解决方案,但都不是很清楚.

I understand there's a few solutions but none of them are so clear.

解决方案 1 - Urban 提出

Solution 1 - Proposed by Urban

$scope.doSomething = ServiceName.functionName;

这里的问题是我有 20 个函数和 10 个控制器.如果我这样做,就意味着要向每个控制器添加大量代码.

The problem here is I have 20 functions and ten controllers. If I did this it would mean adding a lot of code to each controller.

解决方案 2 - 由我提出

    var factory = {

        Setup: function ($scope) {

            $scope.isNotString = function (str) {
                return (typeof str !== "string");
            }

这样做的缺点是,在每个控制器开始时,我都会对通过 $scope 的每个服务进行一个或多个设置调用.

The disadvantage of this is that at the start of every controller I would have one or more of these Setup calls to each service which passed the $scope.

解决方案 3 - Urban 提出

Solution 3 - Proposed by Urban

城市提出的创建通用服务的解决方案看起来不错.这是我的主要设置:

The solution proposed by urban of creating a generic service looks good. Here's my main set up:

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

我应该为此添加通用服务吗?我该怎么做?

Should I add the generic service to this and how could I do it ?

推荐答案

EDIT 7/1/15:

我很久以前写过这个答案,并且有一段时间没有跟上 angular 很多,但似乎这个答案仍然相对流行,所以我想指出几个@nicolas 在下面提出的观点很好.一方面,注入 $rootScope 并在那里附加助手将使您不必为每个控制器添加它们.另外 - 我同意,如果您添加的内容应该被视为 Angular 服务或过滤器,那么它们应该以这种方式被采用到代码中.

I wrote this answer a pretty long time ago and haven't been keeping up a lot with angular for a while, but it seems as though this answer is still relatively popular, so I wanted to point out that a couple of the point @nicolas makes below are good. For one, injecting $rootScope and attaching the helpers there will keep you from having to add them for every controller. Also - I agree that if what you're adding should be thought of as Angular services OR filters, they should be adopted into the code in that manner.

此外,从当前版本 1.4.2 开始,Angular 公开了一个提供者"API,允许将其注入到配置块中.查看这些资源了解更多信息:

Also, as of the current version 1.4.2, Angular exposes a "Provider" API, which is allowed to be injected into config blocks. See these resources for more:

https://docs.angularjs.org/guide/module#module-加载依赖

AngularJS 依赖注入 module.config 内的值

我不认为我会更新下面的实际代码块,因为这些天我并没有真正积极地使用 Angular,而且我真的不想冒险给出一个新答案而不觉得它实际上符合标准到新的最佳实践.如果其他人觉得可以,那就去吧.

I don't think I'm going to update the actual code blocks below, because I'm not really actively using Angular these days and I don't really want to hazard a new answer without feeling comfortable that it's actually conforming to new best practices. If someone else feels up to it, by all means go for it.

编辑 2/3/14:

考虑到这一点并阅读其他一些答案后,我实际上认为我更喜欢@Brent Washburne 和@Amogh Talpallikar 提出的方法的变体.特别是如果您正在寻找 isNotString() 或类似的实用程序.这里的一个明显优势是,您可以在 angular 代码之外重用它们,也可以在配置函数内部使用它们(使用服务无法做到这一点).

After thinking about this and reading some of the other answers, I actually think I prefer a variation of the method brought up by @Brent Washburne and @Amogh Talpallikar. Especially if you're looking for utilities like isNotString() or similar. One of the clear advantages here is that you can re-use them outside of your angular code and you can use them inside of your config function (which you can't do with services).

话虽如此,如果您正在寻找一种通用的方法来重用应该是服务的东西,那么我认为旧的答案仍然是一个不错的答案.

That being said, if you're looking for a generic way to re-use what should properly be services, the old answer I think is still a good one.

我现在要做的是:

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:

controller.js:

angular.module('app.controllers', []).                                                                                                                                                                                  
  controller('firstCtrl', ['$scope', function($scope) {
    $scope.helpers = MyNamespace.helpers;
  });

然后在你的部分你可以使用:

Then in your partial you can use:

<button data-ng-click="console.log(helpers.isNotString('this is a string'))">Log String Test</button>

下面的旧答案:

最好将它们作为服务包含在内.如果您要在多个控制器中重复使用它们,将它们作为服务包含在内将使您不必重复代码.

It might be best to include them as a service. If you're going to re-use them across multiple controllers, including them as a service will keep you from having to repeat code.

如果您想在您的 html 部分中使用服务功能,那么您应该将它们添加到该控制器的作用域中:

If you'd like to use the service functions in your html partial, then you should add them to that controller's scope:

$scope.doSomething = ServiceName.functionName;

然后在你的部分你可以使用:

Then in your partial you can use:

<button data-ng-click="doSomething()">Do Something</button>

这里有一种方法可以让这一切井井有条,免去太多麻烦:

Here's a way you might keep this all organized and free from too much hassle:

将您的控制器、服务和路由代码/配置分成三个文件:controllers.js、services.js 和 app.js.顶层模块是app",它有 app.controllers 和 app.services 作为依赖.然后 app.controllers 和 app.services 可以在它们自己的文件中声明为模块.这个组织结构只是取自 Angular Seed:

Separate your controller, service and routing code/config into three files: controllers.js, services.js, and app.js. The top layer module is "app", which has app.controllers and app.services as dependencies. Then app.controllers and app.services can be declared as modules in their own files. This organizational structure is just taken from Angular Seed:

app.js:

 angular.module('app', ['app.controllers', 'app.services']).                             
   config(['$routeProvider', function($routeProvider) {
     // Routing stuff here...
   }]);  

services.js:

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:

controller.js:

angular.module('app.controllers', []).                                                                                                                                                                                  
  controller('firstCtrl', ['$scope', 'genericServices', function($scope, genericServices) {
    $scope.genericServices = genericServices;
  });

然后在你的部分你可以使用:

Then in your partial you can use:

<button data-ng-click="genericServices.doSomething()">Do Something</button>
<button data-ng-click="genericServices.doSomethingElse()">Do Something Else</button>

这样,您只需向每个控制器添加一行代码,并且能够在可访问该范围的任何地方访问任何服务功能.

That way you only add one line of code to each controller and are able to access any of the services functions wherever that scope is accessible.

这篇关于如何向我的 AngularJS 应用程序添加一些小的实用函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆