คำสั่ง angularjs ควรโต้ตอบโดยตรงกับบริการหรือไม่หรือเป็นรูปแบบการต่อต้าน?


35

อันไหนที่ถือว่าดีกว่า:

  • มีคำสั่งที่โต้ตอบกับบริการโดยตรง

หรือ

  • มีคำสั่งที่แสดง hooks บางอย่างที่ผู้ควบคุมอาจผูกพฤติกรรม (เกี่ยวข้องกับบริการ)?

ฉันต้องการบริบทเพิ่มเติมเกี่ยวกับสิ่งที่คุณต้องการเพื่อให้บรรลุสิ่งที่จะสื่อสารอะไรรหัสแหล่งที่มาที่จะคาดหวังว่าโดเมนของคุณคืออะไรมันจะต้องมีการปรับขนาด?
ผู้ใช้

มันเป็นคำสั่งที่รับผิดชอบในการแสดงวิดเจ็ตการแสดงความคิดเห็น - มันจะแสดงฟิลด์ความคิดเห็นพร้อมกับปุ่มส่ง / ยกเลิก คำสั่งนี้ควรใช้ในบริบทเดียว - แสดงความคิดเห็นใน "เอกสาร" วิธีที่จัดการกับคอนโทรลเลอร์ในปัจจุบันคือการเปิดเผยฟังก์ชั่นสำหรับการสร้างความคิดเห็นที่แท้จริง อีกวิธีหนึ่งในการทำคือห่อหุ้มสิ่งทั้งหมด (พร้อมกับการจัดการข้อผิดพลาด / ความสำเร็จ) ในคำสั่ง (คำสั่งจะได้รับการแสดงความคิดเห็นบริการฉีด)
WTK

คำตอบ:


24

คำสั่งที่ดีที่สุด (เป็นกฎของหัวแม่มือ) เมื่อมันสั้น (รหัสฉลาด), (อาจ) ใช้งานได้อีกครั้งและมีขอบเขต จำกัด ในแง่ของการทำงาน การสร้างคำสั่งที่รวมถึง UI และขึ้นอยู่กับบริการ (ที่ฉันถือว่าจัดการการเชื่อมต่อกับแบ็กเอนด์) ไม่เพียง แต่ให้ 2 หน้าที่การใช้งานนั่นคือ:

  • การควบคุม 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>

ในการเขียนโค้ดของcommentEntrydirective คุณสามารถสร้าง directive เล็ก ๆ ที่มีคอนโทรลเลอร์ที่เชื่อมโยงบริการกับ UI-widget สิ่งที่ต้องการ:

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-controllerแอตทริบิวต์แบบแมนนวลใน HTML: คุณสามารถทำได้โดยใช้คำสั่งตราบใดที่แต่ละคนมีบทบาท "UI" ชัดเจนหรือบทบาท "ข้อมูล" ที่ชัดเจน

มีข้อเสียที่ฉันควรพูดถึง: มันให้ "ชิ้นส่วนเคลื่อนไหว" มากขึ้นในแอปพลิเคชันซึ่งเพิ่มความซับซ้อนเล็กน้อย อย่างไรก็ตามหากแต่ละส่วนมีบทบาทที่ชัดเจนและดี (ทดสอบกับหน่วย + E2E) ฉันจะโต้แย้งว่ามันคุ้มค่าและมีประโยชน์โดยรวมในระยะยาว


59

อนุญาตให้ฉันไม่เห็นด้วยกับคำตอบของ Michal Charemza

แม้ว่าคำตอบของเขาจะถูกต้องตามหลักวิชา แต่มันก็ไม่ได้เป็นจริงสำหรับโลกแห่งความจริง

ฉันกำลังบอกว่าเพราะฉันเคยคิดแบบนั้นและพยายามบังคับใช้มันในแอพขนาดใหญ่ในโลกแห่งความจริงที่ตัวฉันและทีมของฉันกำลังสร้างและมันก็ลำบากเกินไป

การเปรียบเทียบกับภาษา HTML นั้นไม่ค่อยดีนักเนื่องจากคุณไม่ควรพยายามสร้างจุดประสงค์ทั่วไปและคำสั่งที่นำมาใช้ซ้ำได้อย่างมากเพราะคุณไม่ได้สร้างแอปพลิเคชันทั่วไปเช่นเว็บเบราว์เซอร์

แต่คุณควรใช้คำสั่งเพื่อสร้าง Domain Specific Language (DSL) สำหรับแอปของคุณซึ่งอาศัยอยู่ในโดเมนของตัวเอง

นั่นไม่ได้หมายความว่าคำสั่งทั้งหมดไม่ควรเป็นคำสั่งทั่วไป บางคนอาจจะเป็นถ้ามันอยู่ในธรรมชาติของพวกเขา หากคุณกำลังสร้างเครื่องมือเลือกวันที่ที่กำหนดเองโดยทั่วไปแล้วทำให้เป็นเครื่องมือทั่วไปและใช้ซ้ำได้ในแอพ

แต่ถ้าคุณกำลังสร้างบางอย่างเช่นกล่องเข้าสู่ระบบที่ผูกกับส่วนหลังของคุณเพียงแค่ทำมัน

กฎข้อเดียวเท่านั้นที่ควร: อย่าทำซ้ำรหัส (ชิ้นเล็ก ๆ ที่เป็นนามธรรมให้กับโรงงานและบริการ) และทำให้สามารถทดสอบได้ผ่านการฉีดแบบพึ่งพา โชคดีที่ Angular เป็นเค้กชิ้นหนึ่ง

ง่าย ๆ เข้าไว้. :)


5
คะแนนดี Dema - แม้ว่าฉันจะยอมรับคำตอบของ Michal แต่ฉันเห็นด้วยกับแนวทางของคุณว่าเราไม่ควรกระโดดห่วงเพื่อทำสิ่งที่สามารถนำกลับมาใช้ใหม่ได้เพียงเพื่อประโยชน์ของมัน นั่นเป็นสัญชาตญาณเริ่มแรกของฉันจริงๆที่จะผูกมัดการบริการด้วยคำสั่งเพราะมันสมเหตุสมผลไม่ใช่เพราะวิธีการที่ผู้เชี่ยวชาญของกูรูกูลาร์จะทำหรือไม่ทำ ในที่สุดฉันก็สร้างคำสั่งด้วยบริการที่ถูกฉีดเข้าไปโดยตรงและในฐานะที่เป็น API สาธารณะฉันให้เบ็ดสำหรับการโทรกลับที่ถูกไล่ออกหลังจากที่ความคิดเห็นถูกสร้างขึ้นจริง
WTK

2

ฉันคิดว่าคำถาม "คำสั่งโต้ตอบกับบริการ" ควรขึ้นอยู่กับบริการของคุณ

ฉันมีคำสั่งโต้ตอบกับบริการที่ไม่ได้ทำอะไรกับคำขอ HTTP และฉันคิดว่ามันเป็นรูปแบบที่ดี บริการ / โรงงานที่ยอดเยี่ยมสำหรับการห่อหุ้มข้อมูลเชิงตรรกะมากขึ้นและคำสั่งที่ดีสำหรับการห่อหุ้มตรรกะเชิงการนำเสนอ จุดประสงค์ของบริการที่ระบุไว้ในเอกสารเชิงมุมคือ: "คุณสามารถใช้บริการเพื่อจัดระเบียบและแบ่งปันรหัสในแอปของคุณ" ค่อนข้างกว้าง แต่สามารถใช้บริการเพื่อให้บรรลุเป้าหมายดังกล่าวได้

ที่ถูกกล่าวว่าฉันเข้าใจความต้องการในบางกรณีเพื่อให้คำสั่งไม่ทำการร้องขอ HTTP โดยตรง ขึ้นอยู่กับบริการและวิธีการจัดการบริการของคุณอีกครั้ง


1

ตามกรอบ AngularJS เราควรเลือกโรงงาน / บริการเพื่อรับข้อมูลใด ๆ จากเซิร์ฟเวอร์ เพื่อให้โรงงานเหล่านี้สามารถนำกลับมาใช้ใหม่ผ่านแอปพลิเคชันโดยไม่ต้องเขียนเหมือนเดิมอีกครั้งภายในคำสั่งเราสามารถเรียกโรงงานเหล่านี้เพื่อรับข้อมูลที่ดึงมาจาก Api / เซิร์ฟเวอร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.