ฉันสามารถส่งบริการเป็นคำสั่งใน AngularJS ได้หรือไม่?


234

ฉันพยายามฉีดบริการลงในคำสั่งด้านล่าง:

 var app = angular.module('app',[]);
 app.factory('myData', function(){
     return {
        name : "myName"
     }
 });
 app.directive('changeIt',function($compile, myData){
    return {
            restrict: 'C',
            link: function (scope, element, attrs) {
                scope.name = myData.name;
            }
        }
 });

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

คำตอบ:


388

คุณสามารถฉีดคำสั่งและดูเหมือนว่ามันจะทุกที่อื่น

app.directive('changeIt', ['myData', function(myData){
    return {
        restrict: 'C',
        link: function (scope, element, attrs) {
            scope.name = myData.name;
        }
    }
 }]);

13
ฉันคิดว่านี่เป็นวิธีแก้ปัญหาที่ดีกว่าเพราะใช้งานได้แม้ลดขนาดรหัสของคุณลง
czerasz

5
ฉันต้องเพิ่ม '_myData = myData' ก่อนส่งคืน {} จากนั้นอ้างอิงวัตถุเป็น _myData ภายในฟังก์ชันลิงก์
Jelling

ขอบคุณ @Jelling ฉันต้องทำสิ่งเดียวกัน ฉันสงสัยว่ามีใครออกมาที่นั่นบอกเราได้ไหมว่าทำไม ...
sfletche

6
มีเหตุผลใดที่จะฉีด $ compile ในคำสั่ง? ดูเหมือนจะไม่ถูกใช้งานทุกที่
Gru

4
มีวิธีการฉีดถ้าคุณต้องการสร้างฟังก์ชั่นการเชื่อมโยงนอกสายคำสั่ง?
ThinkBonobo

19

เปลี่ยนนิยามคำสั่งของคุณจากไปapp.module app.directiveนอกเหนือจากนั้นทุกอย่างดูดี Btw คุณแทบจะไม่ต้องฉีดบริการเข้าไปในคำสั่ง หากคุณกำลังฉีดบริการ (ซึ่งมักจะเป็นแหล่งข้อมูลหรือรุ่น) ลงในคำสั่งของคุณ (ซึ่งเป็นส่วนหนึ่งของมุมมอง) คุณกำลังสร้างการมีเพศสัมพันธ์โดยตรงระหว่างมุมมองและรูปแบบของคุณ คุณต้องแยกพวกมันออกโดยต่อสายเข้าด้วยกันโดยใช้คอนโทรลเลอร์

มันทำงานได้ดี ฉันไม่แน่ใจว่าคุณกำลังทำสิ่งใดซึ่งผิด นี่คือเสียงอึกทึกของมันทำงาน

http://plnkr.co/edit/M8omDEjvPvBtrBHM84Am


คุณช่วยยกตัวอย่างได้ไหม
ข้อยกเว้น

@ ข้อยกเว้นคุณสามารถใส่รหัสของคุณในซอ? ฉันสามารถดูและดูว่าทำไมรหัสของคุณไม่ทำงานและอาจช่วยให้คุณแก้ไขได้
ganaraj

@Exception เพิ่ม plunk ทำงานที่แสดงรหัสทำงาน
พระมหาราชา

3
ฉันเพิ่งค้นพบบางสิ่งบางอย่าง: ถ้าคุณกำหนดการฉีดในพารามิเตอร์ฟังก์ชั่นfunction($location) { ...แต่ไม่ได้อ้างถึงจริง$locationภายในฟังก์ชั่น AngularJS จะไม่ทำการฉีด ในครั้งเดียวที่คุณจะสังเกตเห็นพฤติกรรมนี้อยู่ในตัวแก้ไขข้อบกพร่อง
วอลเตอร์ Stabosz

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

11

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

template.html

<div my-directive api-service='ServiceName'></div>

my-directive.directive.coffee

angular.module 'my.module'
  .factory 'myDirective', ($injector) ->
    directive = 
      restrict: 'A'
      link: (scope, element, attributes) ->
        scope.apiService = $injector.get(attributes.apiService)

ตอนนี้บริการ 'ไม่ระบุชื่อ' ของคุณพร้อมให้บริการแล้ว หากเป็นเช่น ngResource คุณสามารถใช้อินเตอร์เฟส ngResource มาตรฐานเพื่อรับข้อมูลของคุณ

ตัวอย่างเช่น:

scope.apiService.query((response) ->
  scope.data = response
, (errorResponse) ->
  console.log "ERROR fetching data for service: #{attributes.apiService}"
  console.log errorResponse.data
)

ฉันพบว่าเทคนิคนี้มีประโยชน์มากเมื่อสร้างองค์ประกอบที่โต้ตอบกับจุดสิ้นสุด API โดยเฉพาะ

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