source

Angular에 몇 가지 작은 유틸리티 기능을 추가하는 방법JS 어플리케이션?

manysource 2023. 2. 22. 22:36

Angular에 몇 가지 작은 유틸리티 기능을 추가하는 방법JS 어플리케이션?

내 Angular에 몇 가지 유틸리티 기능을 추가하고 싶다.JS 어플리케이션예를 들어 다음과 같습니다.

$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를 통과한 각 서비스에 대한 이러한 셋업 콜이 1개 이상 발생한다는 것입니다.

해결책 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 services OR 필터라고 생각되는 경우는, 그러한 방법으로 코드에 채용하는 것에 동의합니다.

또한 현재 버전 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.filename:

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.controller:

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 partial에서 서비스 함수를 사용하려면 해당 컨트롤러의 범위에 추가해야 합니다.

$scope.doSomething = ServiceName.functionName;

그런 다음 부분에서는 다음을 사용할 수 있습니다.

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

이 모든 것을 정리하고 번거로움 없이 유지할 수 있는 방법은 다음과 같습니다.

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

app.filename:

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

서비스를 제공합니다.js:

 /* Generic Services */                                                                                                                                                                                                    
 angular.module('app.services', [])                                                                                                                                                                        
   .factory("genericServices", function() {                                                                                                                                                   
     return {                                                                                                                                                                                                              
       doSomething: function() {   
         //Do something here
       },
       doSomethingElse: function() {
         //Do something else here
       }
    });

controller.controller:

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을 통해 rootscope에 추가할 수 있습니다.이 목적을 위해 특정 루트레벨 컨트롤러를 설치할 필요는 없습니다.

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

2°) 코드를 별도의 모듈로 구성할 경우 앵글 서비스 또는 공장 출하시를 사용하여 다음과 같이 런 블록에 전달된 함수에 코드를 주입해야 합니다.

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°) 뷰에서는 대부분의 경우 표시되는 문자열에 포맷을 적용하기 위해 이러한 도우미 기능이 필요합니다.이 마지막 케이스에서 필요한 것은 각도 필터를 사용하는 것입니다.

또한 일부 하위 수준의 도우미 메서드를 각도 서비스 또는 공장에 구성한 경우 필터 생성자 내에 주입하기만 하면 됩니다.

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> 이외)아래에 접속하는 그 외의 컨트롤러는, 그 $스코프를 상속해, 이러한 메서드에 액세스 할 수 있습니다.

유틸리티 기능을 추가하는 가장 쉬운 방법은 이러한 기능을 글로벌 수준으로 유지하는 것입니다.

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

다음으로 (컨트롤러에) 유틸리티 기능을 추가하는 가장 간단한 방법은 이 기능을$scope, 다음과 같이 합니다.

$scope.doSomething = myUtilityFunction;

그러면 이렇게 부를 수 있습니다.

{{ doSomething(x) }}

또는 다음과 같습니다.

ng-click="doSomething(x)"

편집:

첫 번째 질문은 유틸리티 기능을 추가하는 최선의 방법이 서비스를 통한 것인지 여부입니다.기능이 충분히 간단한 경우(예:isNotString()OP에 의해 제공된 예)를 참조해 주세요.

서비스 작성의 이점은 테스트 목적으로 (주입을 통해) 다른 서비스로 대체할 수 있다는 것입니다.극단적으로 말하면, 모든 유틸리티 기능을 컨트롤러에 삽입할 필요가 있습니까?

매뉴얼에서는 컨트롤러에서의 동작을 간단하게 정의하도록 되어 있습니다(예:$scope.double): http://docs.angularjs.org/guide/controller

여기 제가 사용하는 간단하고 컴팩트하고 알기 쉬운 방법이 있습니다.
먼저 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);

}]);

컨트롤러 상속을 사용하면 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>

고정 서비스를 그대로 사용할 수도 있습니다.상수 콜 이외의 함수를 정의하면, 재귀적인 콜도 가능하게 됩니다.

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

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

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