angularjs 지시어가 서비스와 직접 상호 작용해야합니까, 아니면 안티 패턴으로 간주됩니까?


35

어느 것이 더 나은 것으로 간주됩니까?

  • 서비스와 직접 상호 작용하는 지시어

또는

  • 어떤 컨트롤러에 동작을 바인딩 할 수있는 특정 후크를 노출시키는 지시어가 있습니까 (서비스 관련)?

달성하고자하는 것, 전달되는 것, 얼마나 많은 소스 코드를 예상해야하는지, 도메인이 어떻게 확장되어야하는지에 대해 좀 더 많은 맥락이 필요합니다.
사용자

주석 달기 위젯을 렌더링하는 지시문입니다. 주석 필드와 함께 제출 / 취소 버튼이 표시됩니다. 이 지시어는 "문서"에 대해 한 가지 맥락에서만 사용한다고 가정합니다. 현재 컨트롤러를 처리하는 방식은 실제 주석을 작성하기위한 기능을 노출시키는 것입니다 (컨트롤러 get에 주입 된 주석 서비스 인스턴스). 그것을 수행하는 다른 방법은 지시문에 모든 것을 (오류 / 성공 처리와 함께) 캡슐화하는 것입니다 (지시서는 주석 서비스가 주입됩니다).
WTK

답변:


24

지시문은 짧고 (코드 단위), (잠재적으로) 재사용 가능하고 기능 측면에서 범위가 제한된 경우에 가장 좋습니다 (엄지 손가락으로). UI를 포함하고 서비스 (백엔드에 대한 연결을 처리한다고 가정)에 따라 지시문을 작성하면 두 가지 기능적 역할, 즉

  • 위젯에 대한 데이터 표시 / 입력을위한 UI 제어
  • 서비스를 통해 백엔드에 제출

그러나 다른 서비스 또는 다른 UI (적어도 쉽게는 아님)에서 다시 사용할 수 없으므로 재사용 성이 떨어집니다.

이러한 결정을 할 때, 나는 종종 비교 내장 된 HTML 요소 : 예를 들어 <input>, <textarea>또는 <form>: 그들은 어떤 특정 백엔드 완전히 독립적입니다. HTML5는 <input>요소에 몇 가지 추가 유형을 제공했습니다. 예를 들어 date, 여전히 백엔드와 독립적이며 데이터의 정확한 위치 또는 사용 방법. 그것들은 순전히 인터페이스 요소입니다. 지시문을 사용하여 작성된 사용자 정의 위젯은 가능한 경우 동일한 패턴을 따라야한다고 생각합니다.

그러나 이것은 이야기의 끝이 아닙니다. 기본 제공 HTML 요소와의 유사성을 넘어서 서비스를 호출하는 재사용 가능한 지시문을 작성하고을 사용하는 것처럼 순수한 UI 지시문을 사용할 수 있습니다 <textarea>. 다음과 같이 일부 HTML을 사용한다고 가정하십시오.

<document document-url="'documents/3345.html'">
 <document-data></document-data>
 <comments></comments>
 <comment-entry></comment-entry>
</document>

commentEntry지시문 을 코딩하기 위해 서비스를 UI 위젯과 연결하는 컨트롤러 만 포함하는 매우 작은 지시문을 만들 수 있습니다. 다음과 같은 것 :

app.directive('commentEntry', function (myService) {
  return {
    restrict: 'E',
    template: '<comment-widget on-save="save(data)" on-cancel="cancel()"></comment-widget>',
    require: '^document',
    link: function (scope, iElement, iAttrs, documentController) {
      // Allow the controller here to access the document controller
      scope.documentController = documentController;
    },
    controller: function ($scope) {
      $scope.save = function (data) {
        // Assuming the document controller exposes a function "getUrl"
        var url = $scope.documentController.getUrl(); 

        myService.saveComments(url, data).then(function (result) {
          // Do something
        });
      };
    }
  };
});

이것을 극단적으로 고려하면 ng-controllerHTML에 수동 속성 이 필요하지 않을 수도 있습니다 . 각각 직접 명확한 "UI"역할 또는 명확한 "데이터"역할을 갖는 한 지시문을 사용하여 모든 것을 수행 할 수 있습니다.

언급해야 할 단점이 있습니다. 응용 프로그램에 더 많은 "이동 부품"을 제공하므로 약간의 복잡성이 추가됩니다. 그러나 각 부품이 명확한 역할을하고 잘 작동하면 (단위 + E2E 테스트) 가치가 있으며 장기적으로 전반적인 이점이 있다고 주장합니다.


59

Michal Charemza의 답변에 동의하지 않습니다.

그의 대답은 이론적으로는 맞지만 실제 세계에는 그리 실용적이지 않습니다.

나는 그런 식으로 생각하고 자신과 팀이 구축하고 있으며 너무 번거 롭다는 큰 실제 응용 프로그램에서 시행하려고했기 때문에 말하고 있습니다.

웹 브라우저와 같은 일반적인 응용 프로그램을 작성하지 않기 때문에 재사용이 가능한 범용 지시문을 작성하려고 노력해서는 안되기 때문에 HTML 언어와 유사하지 않습니다.

대신, 지시문을 사용하여 자체 도메인에있는 앱의 DSL (Domain Specific Language)을 작성해야합니다.

그렇다고 모든 지시문이 일반적인 것은 아닙니다. 그 특성상 일부가있을 수 있습니다. 사용자 정의 날짜 선택기를 작성하는 경우 반드시 앱 전체에서 일반적이고 재사용 할 수있게하십시오.

그러나 백엔드에 바인딩되는 로그인 상자와 같은 것을 작성하는 경우 그냥 수행하십시오.

경험상 유일한 규칙은 코드를 복제하지 말고 (공장과 서비스에 작은 조각을 추출하지 말고) 의존성 주입을 통해 테스트 할 수 있도록하는 것입니다. 다행히 Angular를 사용하면 케이크 한 조각입니다.

간단하게 유지하십시오. :)


5
좋은 점 Dema-Michal의 답변을 수락했지만 귀하의 접근 방식에 동의합니다. 우리는 그것을 위해 재사용 할 수 있도록 농구대를 뛰어 넘지 않아야합니다. 그것은 angularjs guru의 의도와 행동 방식이 아니라 의미가 있기 때문에 서비스와 지시문을 바인딩하는 최초의 본능이었습니다. 결국에는 서비스에 직접 주입 된 지시문을 작성했으며 공개 API로서 주석이 실제로 작성된 후에 발생하는 콜백에 대한 후크를 제공합니다.
WTK

2

"지시문이 서비스와 상호 작용해야합니까?"라는 질문은 서비스가 수행하는 작업에 따라 다릅니다.

HTTP 요청으로 아무것도하지 않는 서비스와 지시문이 상호 작용했으며 좋은 패턴이라고 생각합니다. 서비스 / 공장은 더 많은 데이터 지향 논리를 캡슐화하는 데 유용하며 지시문은 프리젠 테이션 지향 논리를 캡슐화하는 데 유용합니다. Angular 문서에 명시된 서비스 목적은 "서비스를 사용하여 앱 전체에서 코드를 구성하고 공유 할 수 있습니다."입니다. 꽤 광범위하지만 지시문에서 목표를 달성하기 위해 서비스를 사용할 수 있습니다.

즉, 어떤 경우에는 지시문이 직접 HTTP 요청을하지 않도록하려는 욕구를 이해합니다. 다시 말하지만 서비스와 서비스 구성 방식에 따라 다릅니다.


1

AngularJS 프레임 워크에 따라 서버에서 데이터를 가져 오기 위해 팩토리 / 서비스를 싱글 톤해야합니다. 이러한 팩토리는 동일한 것을 다시 작성하지 않고도 응용 프로그램에서 재사용 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.