programing

AngularJS: 컨트롤러와 공장/서비스는 어떻게 풍부하고 계층적인 객체 모델을 사용하여 구조화해야 합니까?

instargram 2023. 2. 26. 09:01
반응형

AngularJS: 컨트롤러와 공장/서비스는 어떻게 풍부하고 계층적인 객체 모델을 사용하여 구조화해야 합니까?

나는 이 두 개의 훌륭한 기사를 읽었다.

Jonathan Creamer의 angularjs 컨트롤러 상태

그리고.

각도 재고Todd 모토별 JS 컨트롤러

이 기사에서 저자는 컨트롤러를 사용하는 올바른 방법(뷰와 모델을 연결하는 빈약한 가교)과 공장/서비스(비즈니스 로직이 실제로 존재해야 하는 곳)에 대해 설명합니다.

이것은 훌륭한 정보입니다.프로젝트 중 하나에서 컨트롤러를 리팩터링할 수 있게 되어 매우 기뻤습니다만, 풍부한 오브젝트 모델을 사용하고 있는 경우는, 기사에 기재되어 있는 구조가 곧바로 망가지는 것을 알 수 있었습니다.

다음은 "Reshinking Angularjs Controllers"의 설정 개요입니다.

컨트롤러는 다음과 같습니다.

app.controller('InboxCtrl', function InboxCtrl (InboxFactory) {

    var vm = this;

    vm.messages = InboxFactory.messages;

    vm.openMessage = function (message) {
      InboxFactory.openMessage(message);
    };

    vm.deleteMessage = function (message) {
      InboxFactory.deleteMessage(message);
    };

    InboxFactory
      .getMessages()
      .then(function () {
      vm.messages = InboxFactory.messages;
    });

});

여기 공장이 있습니다.

app.factory('InboxFactory', function InboxFactory ($location, NotificationFactory) {

  factory.messages = [];

  factory.openMessage = function (message) {
    $location.search('id', message.id).path('/message');
  };

  factory.deleteMessage = function (message) {
    $http.post('/message/delete', message)
    .success(function (data) {
      factory.messages.splice(index, 1);
      NotificationFactory.showSuccess();
    })
    .error(function () {
      NotificationFactory.showError();
    });
  };

  factory.getMessages = function () {
    return $http.get('/messages')
    .success(function (data) {
      factory.messages = data;
    })
    .error(function () {
      NotificationFactory.showError();
    });
  };

  return factory;

});

.왜냐하면 ★★★★★★★★★★★★★★★★★★★★★★providers출하시)는는 뷰 에서 새로고침할 없이 할 수

이것은 최상위 오브젝트일 경우 정상적으로 동작합니다.하지만 그렇지 않으면 어떻게 될까요?만약 이것이 다른 사용자의 받은 편지함을 보기 위한 앱이라면?관리자는 임의의 사용자의 받은 편지함을 관리하고 참조할 수 있어야 합니다.여러 사용자의 받은 편지함을 동시에 로드해야 할 수도 있습니다.이게 어떻게 작동하나요?문제는 받은 편지함 메시지가 서비스에 저장된다는 것입니다.InboxFactory.messages.

계층이 다음과 같으면 어떻게 될까요?

                           Organization
                                |
              __________________|____________________
             |                  |                    |
         Accounting       Human Resources            IT
             |                  |                    |
     ________|_______      _____|______        ______|________
    |        |       |    |     |      |      |      |        |
   John     Mike    Sue  Tom   Joe    Brad   May    Judy     Jill
    |        |       |    |     |       |     |      |        |
   Inbox    Inbox  Inbox Inbox Inbox  Inbox Inbox  Inbox    Inbox

, 이제messages계층 내 깊은 곳에 있으며 그 자체로는 의미가 없습니다.수 .InboxFactory.messages한 번에 여러 사용자의 메시지를 가져와야 하기 때문입니다.

제 、 Organization Factory 、 Department Factory 、 User Factory 、 Inbox Factory 。" 검색은 "메시지"의 합니다.user의 사람.department 문맥상으로는요, 문맥상으로는요.organization하면 좋을까요?떻게게 회수 ?? ???

그럼 이 문제를 어떻게 해결해야 할까요?컨트롤러, 공장/서비스 및 리치 객체 모델은 어떻게 구성되어야 합니까?

현시점에서는, 풍부한 오브젝트 모델은 가지지 않고, 슬림한 상태로 유지하려고 생각하고 있습니다.컨트롤러에 삽입된 $scope에 객체를 저장하고 새로운 뷰로 이동하면 API에서 새로고침합니다.여러 뷰에서 데이터를 유지해야 하는 경우 서비스나 공장에서 브릿지를 구축할 수 있지만 대부분의 작업을 수행할 수는 없습니다.

다른 사람들은 어떻게 이 문제를 해결했을까요?여기에 어떤 패턴이 있을까요?

리치 오브젝트 모델을 사용할 수 있지만 최상위 레벨이 아닌 오브젝트의 경우 공장에서는 싱글톤으로 사용하는 것이 아니라 새로운 인스턴스를 작성하기 위한 API를 공개해야 합니다.이것은 오브젝트 지향보다 기능성이 뛰어난 요즘의 많은 앱의 설계와는 다소 반대되는 것입니다.어느 쪽의 어프로치의 장점과 단점에 대해서는 코멘트를 하고 있지 않습니다.또, Angular가 어느쪽을 채용하도록 강요하고 있다고는 생각하지 않습니다.

유사 코드로 재설계된 예:

app.controller('InboxCtrl', function InboxCtrl (InboxFactory) {

   var inbox = InboxFactory.createInbox();

   $scope.getMessages = function(){
      inbox.getMessages()
           .then(...)

   $scope.deleteMessages = function(){
      inbox.deleteMessages()
           .then(...)

});

의 어프로치 la 루루 approach approach approach ( ( ( ( ( (, a)를 채용하면, 은 훨씬 심플해집니다.ngRoute않은 이치노 「 」 「 」 、 「 」

app.config(function($routeProvider) {
  $routeProvider
    .when('/inbox/:inboxId',
      templateUrl: 'views/inbox.html',
      controller: 'InboxCtrl',
      controllerAs: 'inbox',
      resolve: {
        inboxMessages: function(InboxFactory) {
          // Use use :inboxId route param if you need to work with multiple
          // inboxes. Taking some libery here, we'll assuming
          // `InboxFactory.getMessages()` returns a promise that will resolve to
          // an array of messages;
          return InboxFactory.getMessages();
        }
      }
    // ... other routes
    .otherwise: {
      // ...
    };
});

app.controller('InboxCtrl', function InboxCtrl (InboxFactory, inboxMessages) {
  var vm = this;
  vm.messages = inboxMessages;
  vm.openMessage = InboxFactory.openMessage;
  vm.deleteMessage = InboxFactory.deleteMessage;
});

이제 컨트롤러가 얼마나 슬림해졌는지 보세요!물론 몇 군데에서 좀 더 콤팩트한 구문을 사용했지만, 컨트롤러가 실제로 어떻게 서로 결합하고 있는지 잘 보여줍니다.

더 , , 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다.InboxFactory.messages제로언 언용 ?용? ????그 .InboxFactory.getMessages이 약속은 메시지 자체에 대해 해결하도록 합시다.

이러한 방법으로 데이터를 싱글톤으로 저장하는 것이 가장 쉬운 해결책일 수 있지만 데이터를 즉시 가져와야 하는 경우에는 생활이 어려워집니다.API와 공장(AlexMA가 권장하는 바와 같이)에 의존하여 경로가 변경될 때마다 필요한 데이터(예를 들어 사용자가 다른 수신 트레이를 보고 싶어 하는 경우)를 추출하여 해당 데이터를 적절한 컨트롤러에 직접 주입하는 것이 가장 좋습니다.

이 폼의 또 다른 장점은 컨트롤러 인스턴스화 시 데이터를 수중에 넣을 수 있다는 것입니다.비동기 상태를 곡예하거나 콜백에 많은 코드를 넣을 걱정을 할 필요가 없습니다.결과적으로 새로운 수신 트레이 뷰를 표시하기 전에 데이터 로딩 에러를 검출할 수 있어, 유저가 어중간한 상태가 되는 일은 없습니다.

또한 풍부한 모델 구조가 어떻게 조합되는지 알아야 하는 부담은 컨트롤러의문의 요점은 풍부한 모델 구조가 어떻게 조합되는지를 파악하는 것입니다.데이터를 수집하여 다양한 방법을 뷰에 표시합니다.

여러 가지 방법을 손보고 시도해 본 후, 저의 최종 결정은 풍부한 객체 모델을 여러 뷰에 걸쳐 고집해서는 안 된다는 것입니다.

오브젝트 모델을 매우 희박하게 유지하고 각 뷰에 필요한 대로 로드합니다.보관하고 있는 높은 수준의 데이터(이름, ID, 이메일 등 사용자 정보 및 로그인한 조직 등의 조직 데이터)가 있지만 다른 데이터는 모두 현재 보기에 로드됩니다.

이러한 린 어프로치를 채용하면, 우리 공장은 다음과 같이 됩니다.

app.factory('InboxFactory', function InboxFactory ($location, NotificationFactory) {

factory.messages = [];

factory.openMessage = function (message) {
  $location.search('id', message.id).path('/message');
};

factory.deleteMessage = function (message) {
  $http.post('/message/delete', message)
  .success(function (data) {
    NotificationFactory.showSuccess();
    return data;
  })
  .error(function () {
    NotificationFactory.showError();
    return null;
  });
};

factory.getMessages = function (userId) {
  return $http.get('/messages/user/id/'+userId)
  .success(function (data) {
    return data;
  })
  .error(function () {
    NotificationFactory.showError();
    return null;
  });
};

return factory;

});

컨트롤러:

app.controller('InboxCtrl', function InboxCtrl (InboxFactory) {

  var vm = this;

  vm.messages = {};

  vm.openMessage = function (message) {
    InboxFactory.openMessage(message);
  };

  vm.deleteMessage = function (message) {
    InboxFactory.deleteMessage(message);
  };

  InboxFactory
    .getMessages(userId) //you can get the userId from anywhere you want.
    .then(function (data) {
      vm.messages = data;
  });

});

지금까지의 이점은 다음과 같습니다.

  • 단순화된 응용 프로그램 논리
  • 슬림형 경량형(현재 상태에 필요한 것만 로드)
  • 메모리 사용량을 줄임으로써 전체적인 퍼포먼스가 향상됩니다.특히 모바일에서는요.

언급URL : https://stackoverflow.com/questions/29683316/angularjs-how-should-controllers-and-factories-services-be-structured-with-a-r

반응형