Programing

AngularJS 애플리케이션에 작은 유틸리티 기능을 어떻게 추가 할 수 있습니까?

lottogame 2020. 6. 15. 08:18
반응형

AngularJS 애플리케이션에 작은 유틸리티 기능을 어떻게 추가 할 수 있습니까?


AngularJS 응용 프로그램에 일부 유틸리티 기능을 추가하고 싶습니다. 예를 들면 다음과 같습니다.

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

서비스로 추가하는 가장 좋은 방법입니까? 내가 읽은 것에서이 작업을 수행 할 수 있지만 HTML 페이지에서이를 사용하고 싶습니다. 서비스에있는 경우 여전히 가능합니까? 예를 들어 다음을 사용할 수 있습니다.

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

누군가 내가 어떻게 이것을 추가 할 수 있는지 예를 들어 줄 수 있습니까? 서비스를 만들거나 다른 방법이 있습니까? 가장 중요한 것은 이러한 유틸리티 기능을 파일로 만들고 기본 설정의 다른 부분과 결합하지 않기를 원합니다.

나는 몇 가지 해결책이 있지만 그중 어느 것도 명확하지 않다는 것을 이해합니다.

솔루션 1 -Urban에서 제안

$scope.doSomething = ServiceName.functionName;

여기서 문제는 20 개의 기능과 10 개의 컨트롤러가 있다는 것입니다. 내가 이것을했다면 각 컨트롤러에 많은 코드를 추가하는 것을 의미합니다.

해결책 2- 내가 제안

    var factory = {

        Setup: function ($scope) {

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

이것의 단점은 모든 컨트롤러가 시작될 때 $ scope를 통과 한 각 서비스에 대해 하나 이상의 이러한 설정 호출이 있다는 것입니다.

솔루션 3 -Urban에서 제안

일반 서비스를 작성하기 위해 도시에서 제안한 솔루션이 좋습니다. 내 주요 설정은 다음과 같습니다.

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 편집 :

나는 꽤 오래 전에이 답변을 썼고 한동안 각도를 많이 유지하지 않았지만이 답변이 여전히 상대적으로 인기가있는 것처럼 보이므로 @nicolas 아래는 좋습니다. 우선, $ rootScope를 주입하고 헬퍼를 연결하면 모든 컨트롤러에 추가 할 필요가 없습니다. 또한 추가하는 것이 Angular 서비스 또는 필터로 생각되어야하는 경우 그러한 방식으로 코드에 채택되어야한다는 데 동의합니다.

또한 현재 버전 1.4.2부터 Angular는 "Provider"API를 제공하며이 블록은 구성 블록에 주입 될 수 있습니다. 자세한 내용은 다음 자료를 참조하십시오.

https://docs.angularjs.org/guide/module#module-loading-dependencies

module.config 내부의 값에 대한 AngularJS 종속성 주입

요즘 Angular를 실제로 적극적으로 사용하지 않고 실제로 새로운 베스트를 준수한다는 것을 느끼지 않고 새로운 답변을 위험에 빠뜨리고 싶지 않기 때문에 아래의 실제 코드 블록을 업데이트 할 것이라고 생각하지 않습니다. 관행. 다른 사람이 그것에 대해 느끼면 반드시 그것을 찾으십시오.

2/3/14 편집 :

이것에 대해 생각하고 다른 답변을 읽은 후에 실제로 @Brent Washburne과 @Amogh Talpallikar가 가져온 방법의 변형을 선호한다고 생각합니다. 특히 isNotString () 또는 이와 유사한 유틸리티를 찾고 있다면. 여기서 명백한 장점 중 하나는 각도 코드 외부에서 다시 사용할 수 있으며 구성 기능 내에서 사용할 수 있다는 것입니다 (서비스로는 할 수 없음).

즉, 서비스를 올바르게 사용해야하는 일반적인 재사용 방법을 찾고 있다면 이전의 대답은 여전히 ​​좋은 방법이라고 생각합니다.

내가 지금 할 일은 :

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>

이 모든 것을 체계적으로 유지하고 너무 번거 로움을 없애는 방법은 다음과 같습니다.

컨트롤러, 서비스 및 라우팅 코드 / 구성을 controllers.js, services.js 및 app.js의 세 파일로 분리하십시오. 최상위 계층 모듈은 "app"이며 app.controllers 및 app.services를 종속성으로 사용합니다. 그런 다음 app.controllers 및 app.services를 자체 파일에서 모듈로 선언 할 수 있습니다. 이 조직 구조는 Angular Seed 에서 가져온 것입니다 .

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>

이렇게하면 각 컨트롤러에 한 줄의 코드 만 추가하고 해당 범위에 액세스 할 수있는 모든 서비스 기능에 액세스 할 수 있습니다.


이 오래된 실에 와서 나는 그것을 강조하고 싶었다.

1 °) 유틸리티 기능은 module.run을 통해 루트 스코프에 추가해야합니다. 이 목적을 위해 특정 루트 레벨 컨트롤러를 설치할 필요는 없습니다.

angular.module('myApp').run(function($rootScope){
  $rootScope.isNotString = function(str) {
   return (typeof str !== "string");
  }
});

2°) If you organize your code into separate modules you should use angular services or factory and then inject them into the function passed to the run block, as follow:

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°) My understanding is that in views, for most of the cases you need these helper functions to apply some kind of formatting to strings you display. What you need in this last case is to use angular filters

And if you have structured some low level helper methods into angular services or factory, just inject them within your filter constructor :

angular.module('myApp').filter('myFilter', function(myHelperMethods){ 
  return function(aString){
    if (myHelperMethods.isNotString(aString)){
      return 
    }
    else{
      // something else 
    }
  }
);

And in your view :

{{ aString | myFilter }}   

Do I understand correctly that you just want to define some utility methods and make them available in templates?

You don't have to add them to every controller. Just define a single controller for all the utility methods and attach that controller to <html> or <body> (using the ngController directive). Any other controllers you attach anywhere under <html> (meaning anywhere, period) or <body> (anywhere but <head>) will inherit that $scope and will have access to those methods.


The easiest way to add utility functions is to leave them at the global level:

function myUtilityFunction(x) { return "do something with "+x; }

Then, the simplest way to add a utility function (to a controller) is to assign it to $scope, like this:

$scope.doSomething = myUtilityFunction;

Then you can call it like this:

{{ doSomething(x) }}

or like this:

ng-click="doSomething(x)"

EDIT:

The original question is if the best way to add a utility function is through a service. I say no, if the function is simple enough (like the isNotString() example provided by the OP).

The benefit of writing a service is to replace it with another (via injection) for the purpose of testing. Taken to an extreme, do you need to inject every single utility function into your controller?

The documentation says to simply define behavior in the controller (like $scope.double): http://docs.angularjs.org/guide/controller


Here is a simple, compact and easy to understand method I use.
First, add a service in your 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;

    }]);

Then, in your controller, inject your helper object and use any available function with something like the following:

app.controller('MainCtrl', [

'$scope',
'Helpers',

function($scope, Helpers){

    $scope.sayIt = Helpers.getFooBar("Hello");
    console.log($scope.sayIt);

}]);

You can also use the constant service as such. Defining the function outside of the constant call allows it to be recursive as well.

function doSomething( a, b ) {
    return a + b;
};

angular.module('moduleName',[])
    // Define
    .constant('$doSomething', doSomething)
    // Usage
    .controller( 'SomeController', function( $doSomething ) {
        $scope.added = $doSomething( 100, 200 );
    })
;

Why not use controller inheritance, all methods/properties defined in scope of HeaderCtrl are accessible in the controller inside ng-view. $scope.servHelper is accessible in all your controllers.

    angular.module('fnetApp').controller('HeaderCtrl', function ($scope, MyHelperService) {
      $scope.servHelper = MyHelperService;
    });


<div ng-controller="HeaderCtrl">
  <div ng-view=""></div>
</div>

참고URL : https://stackoverflow.com/questions/19614545/how-can-i-add-some-small-utility-functions-to-my-angularjs-application

반응형