Should angularjs directive directly interact with services or is it considered an anti-pattern?

Which one is considered better:

  • having a directive that interacts with services directly

or

  • having a directive that exposes certain hooks to which controller may bind behaviour (involving services)?

2

A directive is best (as a rule-of-thumb) when it’s short (code-wise), (potentially) re-usable, and has a limited a scope in terms of functionality. Making a directive that includes UI and depends on a service (that I assume handles connection to the backend), not only gives it 2 functional roles, namely:

  • Controlling the UI for display/entry of data for the widget.
  • Submitting to the backend (via the service).

but also making it less re-usable, as you then can’t use it again with another service, or with a different UI (at least not easily).

When making these decisions, I often compare to the built-in HTML elements: for example <input>, <textarea> or <form>: they are completely independent of any specific backend. HTML5 has given the <input> element a few extra types, e.g. date, which is still independent of backend, and where exactly the data goes or how it is used. They are purely interface elements. Your custom widgets, built using directives, I think should follow the same pattern, if possible.

However, this isn’t the end of the story. Going beyond the analogy with the built-in HTML elements, you can create re-usable directives that both call services, and use a purely UI directive, just like it might use a <textarea>. Say you want to use some HTML as follows:

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

To code up the commentEntry directive, you could make a very small directive that just contains the controller that links up a service with a UI-widget. Something like:

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

Taking this to an extreme, you might not ever need to have a manual ng-controller attribute in the HTML: you can do it all using directives, as long as each directly has a clear “UI” role, or a clear “data” role.

There is a downside I should mention: it gives more “moving parts” to the application, which adds a bit of complexity. However, if each part has a clear role, and is well (unit + E2E tested), I would argue it’s worth it and an overall benefit in the long term.

Allow me to disagree with Michal Charemza answer.

Although his answer is theoretically correct, it is not very practical for the real world.

I am saying that because I used to think like that and tried to enforce it on a large real world app that myself and my team are building and it just became too troublesome.

The analogy to the HTML language is not good, because you should not strive to build general purpose, extremely reusable directives, because you’re not building a generic application like a web browser.

Instead, you should use the directives to build a Domain Specific Language (DSL) for your app, that lives on its own domain.

That does not mean that all directives should not be generic. Some might be, if it’s in their nature. If you’re building a custom date picker, by all means make it generic and reusable across apps.

But if you’re building something like a login box that binds to your back-end, just do it.

The only rule of thumb should be: do not ever duplicate code (abstract little pieces to factories and services) and make it testable through dependency injection. Fortunately, with Angular, those are a piece of cake.

Keep it simple. 🙂

1

I think the “should a directive interact with a service” question depends on what your service is doing.

I’ve had directives interact with services that don’t do anything with HTTP requests and I think it’s a good pattern. Services/Factories are great for encapsulating more data oriented logic, and directives are great for encapsulating presentation oriented logic. The stated purpose of services in the Angular docs are: “You can use services to organize and share code across your app.”. That’s pretty broad but services can be used to achieve that goal in directives.

That being said, I do understand the desire in some cases to make it so that directives do not directly make any HTTP requests. Again, it depends on the service and how you’re organizing your services.

As per AngularJS framework , we should singleton factories/services for getting any data from server. So that these factories can be reused across application without rewriting the same.Well inside directive we can call these factories to get data fetched from Api/server.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Should angularjs directive directly interact with services or is it considered an anti-pattern?

Which one is considered better:

  • having a directive that interacts with services directly

or

  • having a directive that exposes certain hooks to which controller may bind behaviour (involving services)?

2

A directive is best (as a rule-of-thumb) when it’s short (code-wise), (potentially) re-usable, and has a limited a scope in terms of functionality. Making a directive that includes UI and depends on a service (that I assume handles connection to the backend), not only gives it 2 functional roles, namely:

  • Controlling the UI for display/entry of data for the widget.
  • Submitting to the backend (via the service).

but also making it less re-usable, as you then can’t use it again with another service, or with a different UI (at least not easily).

When making these decisions, I often compare to the built-in HTML elements: for example <input>, <textarea> or <form>: they are completely independent of any specific backend. HTML5 has given the <input> element a few extra types, e.g. date, which is still independent of backend, and where exactly the data goes or how it is used. They are purely interface elements. Your custom widgets, built using directives, I think should follow the same pattern, if possible.

However, this isn’t the end of the story. Going beyond the analogy with the built-in HTML elements, you can create re-usable directives that both call services, and use a purely UI directive, just like it might use a <textarea>. Say you want to use some HTML as follows:

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

To code up the commentEntry directive, you could make a very small directive that just contains the controller that links up a service with a UI-widget. Something like:

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

Taking this to an extreme, you might not ever need to have a manual ng-controller attribute in the HTML: you can do it all using directives, as long as each directly has a clear “UI” role, or a clear “data” role.

There is a downside I should mention: it gives more “moving parts” to the application, which adds a bit of complexity. However, if each part has a clear role, and is well (unit + E2E tested), I would argue it’s worth it and an overall benefit in the long term.

Allow me to disagree with Michal Charemza answer.

Although his answer is theoretically correct, it is not very practical for the real world.

I am saying that because I used to think like that and tried to enforce it on a large real world app that myself and my team are building and it just became too troublesome.

The analogy to the HTML language is not good, because you should not strive to build general purpose, extremely reusable directives, because you’re not building a generic application like a web browser.

Instead, you should use the directives to build a Domain Specific Language (DSL) for your app, that lives on its own domain.

That does not mean that all directives should not be generic. Some might be, if it’s in their nature. If you’re building a custom date picker, by all means make it generic and reusable across apps.

But if you’re building something like a login box that binds to your back-end, just do it.

The only rule of thumb should be: do not ever duplicate code (abstract little pieces to factories and services) and make it testable through dependency injection. Fortunately, with Angular, those are a piece of cake.

Keep it simple. 🙂

1

I think the “should a directive interact with a service” question depends on what your service is doing.

I’ve had directives interact with services that don’t do anything with HTTP requests and I think it’s a good pattern. Services/Factories are great for encapsulating more data oriented logic, and directives are great for encapsulating presentation oriented logic. The stated purpose of services in the Angular docs are: “You can use services to organize and share code across your app.”. That’s pretty broad but services can be used to achieve that goal in directives.

That being said, I do understand the desire in some cases to make it so that directives do not directly make any HTTP requests. Again, it depends on the service and how you’re organizing your services.

As per AngularJS framework , we should singleton factories/services for getting any data from server. So that these factories can be reused across application without rewriting the same.Well inside directive we can call these factories to get data fetched from Api/server.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật