Chỉ thị angularjs có nên tương tác trực tiếp với các dịch vụ hay nó được coi là một mô hình chống?


35

Cái nào được coi là tốt hơn:

  • có một chỉ thị tương tác trực tiếp với các dịch vụ

hoặc là

  • có một lệnh chỉ ra các móc nhất định mà bộ điều khiển có thể ràng buộc hành vi (liên quan đến các dịch vụ) không?

Tôi sẽ cần thêm một chút bối cảnh về những gì bạn muốn đạt được, những gì được truyền đạt, bao nhiêu mã nguồn được mong đợi tên miền của bạn là gì, nó phải mở rộng như thế nào?
Người dùng

Đây là một lệnh chịu trách nhiệm hiển thị tiện ích bình luận - nó hiển thị trường bình luận, cùng với các nút gửi / hủy. Lệnh này được cho là chỉ được sử dụng trong một ngữ cảnh - bình luận về "tài liệu". Cách thức mà bộ điều khiển hiện đang xử lý là bộc lộ các chức năng để tạo nhận xét thực tế (bộ điều khiển được đưa vào dịch vụ bình luận). Một cách khác để làm điều đó là gói gọn toàn bộ (cùng với xử lý lỗi / xử lý thành công) trong một lệnh (lệnh sẽ nhận được dịch vụ bình luận được đưa vào).
WTK

Câu trả lời:


24

Một lệnh là tốt nhất (dưới dạng quy tắc) khi nó ngắn (mã thông minh), (có khả năng) có thể sử dụng lại và có phạm vi giới hạn về chức năng. Tạo một lệnh bao gồm UI và phụ thuộc vào một dịch vụ (mà tôi giả sử xử lý kết nối với phụ trợ), không chỉ cung cấp cho nó 2 vai trò chức năng, cụ thể là:

  • Kiểm soát UI để hiển thị / nhập dữ liệu cho widget.
  • Đệ trình phụ trợ (thông qua dịch vụ).

nhưng cũng làm cho nó ít sử dụng lại được, vì sau đó bạn không thể sử dụng lại với dịch vụ khác hoặc với một giao diện người dùng khác (ít nhất là không dễ dàng).

Khi đưa ra những quyết định này, tôi thường so sánh với built-in phần tử HTML: ví dụ <input>, <textarea>hay <form>: họ là hoàn toàn độc lập của bất kỳ cụ phụ trợ. HTML5 đã cung cấp cho <input>phần tử một vài loại bổ sung, ví dụ date, vẫn độc lập với phụ trợ và nơi chính xác dữ liệu đi hoặc cách sử dụng. Chúng hoàn toàn là các yếu tố giao diện. Các widget tùy chỉnh của bạn, được xây dựng bằng chỉ thị, tôi nghĩ nên theo cùng một mẫu, nếu có thể.

Tuy nhiên, đây không phải là kết thúc của câu chuyện. Vượt xa sự tương tự với các yếu tố HTML tích hợp, bạn có thể tạo các chỉ thị có thể sử dụng lại, vừa gọi dịch vụ, vừa sử dụng chỉ thị UI hoàn toàn, giống như nó có thể sử dụng a <textarea>. Giả sử bạn muốn sử dụng một số HTML như sau:

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

Để mã hóa commentEntrychỉ thị, bạn có thể tạo một lệnh rất nhỏ chỉ chứa bộ điều khiển liên kết dịch vụ với tiện ích UI. Cái gì đó như:

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

Đưa điều này đến mức cực đoan, bạn có thể không cần phải có ng-controllerthuộc tính thủ công trong HTML: bạn có thể thực hiện tất cả bằng cách sử dụng các lệnh, miễn là mỗi trực tiếp có vai trò "UI" rõ ràng hoặc vai trò "dữ liệu" rõ ràng.

Có một nhược điểm tôi nên đề cập: nó cung cấp nhiều "bộ phận chuyển động" hơn cho ứng dụng, điều này làm tăng thêm một chút phức tạp. Tuy nhiên, nếu mỗi phần có vai trò rõ ràng và tốt (đơn vị + E2E đã được kiểm tra), tôi sẽ cho rằng nó đáng giá và lợi ích chung trong dài hạn.


59

Cho phép tôi không đồng ý với câu trả lời của Michal Charemza.

Mặc dù câu trả lời của ông là đúng về mặt lý thuyết, nhưng nó không thực tế cho thế giới thực.

Tôi đang nói rằng bởi vì tôi đã từng nghĩ như vậy và cố gắng thực thi nó trên một ứng dụng thế giới thực lớn mà bản thân tôi và nhóm của tôi đang xây dựng và nó trở nên quá rắc rối.

Sự tương tự với ngôn ngữ HTML là không tốt, vì bạn không nên cố gắng xây dựng mục đích chung, các chỉ thị cực kỳ có thể sử dụng lại, vì bạn không xây dựng một ứng dụng chung như trình duyệt web.

Thay vào đó, bạn nên sử dụng các chỉ thị để xây dựng Ngôn ngữ cụ thể miền (DSL) cho ứng dụng của mình, nằm trên miền riêng của nó.

Điều đó không có nghĩa là tất cả các chỉ thị không nên chung chung. Một số có thể, nếu đó là trong bản chất của họ. Nếu bạn đang xây dựng một công cụ chọn ngày tùy chỉnh, bằng mọi cách, hãy làm cho nó chung chung và có thể sử dụng lại trên các ứng dụng.

Nhưng nếu bạn đang xây dựng một cái gì đó giống như một hộp đăng nhập liên kết với back-end của bạn, chỉ cần làm điều đó.

Nguyên tắc duy nhất nên là: không bao giờ sao chép mã (các mẩu nhỏ trừu tượng cho các nhà máy và dịch vụ) và làm cho nó có thể kiểm tra được thông qua việc tiêm phụ thuộc. May mắn thay, với Angular, đó là một miếng bánh.

Giữ cho nó đơn giản. :)


5
Điểm tốt Dema - mặc dù tôi đã chấp nhận câu trả lời của Michal nhưng tôi đồng ý với cách tiếp cận của bạn, rằng chúng ta không nên nhảy vòng để làm cho một cái gì đó có thể tái sử dụng chỉ vì lợi ích của nó. Đó thực sự là bản năng ban đầu của tôi, để ràng buộc dịch vụ với chỉ thị, bởi vì nó có ý nghĩa, không phải vì đó là cách mà angularjs guru sẽ hoặc không làm điều đó. Cuối cùng, tôi đã tạo ra lệnh với dịch vụ được tiêm trực tiếp vào nó và như một API công khai, tôi cung cấp một móc nối cho một cuộc gọi lại được thực hiện sau khi các bình luận thực sự được tạo ra.
WTK

2

Tôi nghĩ rằng câu hỏi "nên chỉ thị tương tác với dịch vụ" phụ thuộc vào dịch vụ của bạn đang làm gì.

Tôi đã có các chỉ thị tương tác với các dịch vụ không làm gì với các yêu cầu HTTP và tôi nghĩ đó là một mô hình tốt. Dịch vụ / nhà máy là tuyệt vời để đóng gói logic định hướng dữ liệu nhiều hơn và các chỉ thị là tuyệt vời để đóng gói logic hướng trình bày. Mục đích đã nêu của các dịch vụ trong tài liệu Angular là: "Bạn có thể sử dụng các dịch vụ để sắp xếp và chia sẻ mã trên ứng dụng của mình.". Điều đó khá rộng nhưng các dịch vụ có thể được sử dụng để đạt được mục tiêu đó trong các chỉ thị.

Điều đó đang được nói, tôi hiểu được mong muốn trong một số trường hợp để thực hiện nó để các chỉ thị không trực tiếp thực hiện bất kỳ yêu cầu HTTP nào. Một lần nữa, nó phụ thuộc vào dịch vụ và cách bạn tổ chức dịch vụ của mình.


1

Theo khung AngularJS, chúng ta nên sử dụng các nhà máy / dịch vụ đơn lẻ để nhận bất kỳ dữ liệu nào từ máy chủ. Để các nhà máy này có thể được sử dụng lại trên toàn bộ ứng dụng mà không cần viết lại như vậy. Trong lệnh này, chúng tôi có thể gọi các nhà máy này để lấy dữ liệu từ Api / máy chủ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.