Tôi có thể tiêm dịch vụ vào chỉ thị trong AngularJS không?


234

Tôi đang cố gắng tiêm một dịch vụ vào một chỉ thị như dưới đây:

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

Nhưng điều này đang trả lại cho tôi một lỗi Unknown provider: myDataProvider. Ai đó có thể vui lòng nhìn vào mã và cho tôi biết nếu tôi đang làm gì sai?

Câu trả lời:


388

Bạn có thể thực hiện tiêm trên Chỉ thị, và có vẻ như nó làm ở mọi nơi khác.

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

13
Tôi nghĩ rằng đây là một giải pháp tốt hơn bởi vì nó hoạt động ngay cả sau khi thu nhỏ mã của bạn.
czerasz

5
Tôi đã phải thêm '_myData = myData' trước khi trả về {} và sau đó tham chiếu đối tượng là _myData bên trong hàm liên kết.
Jelling

Cảm ơn @Jelling. Tôi đã phải làm điều tương tự. Tôi tự hỏi nếu có ai ngoài đó có thể cho chúng tôi biết tại sao ...?
sfletche

6
bất kỳ lý do cụ thể để tiêm $ biên dịch trong chỉ thị? nó dường như không được sử dụng ở bất cứ đâu.
gru

4
Có một giải pháp để tiêm nếu bạn muốn tạo chức năng liên kết bên ngoài lệnh gọi?
ThinkBonobo

19

Thay đổi định nghĩa chỉ thị của bạn từ app.moduleđến app.directive. Ngoài ra mọi thứ có vẻ tốt. Btw, rất hiếm khi bạn phải tiêm dịch vụ vào một chỉ thị. Nếu bạn đang đưa một dịch vụ (thường là nguồn dữ liệu hoặc mô hình) vào chỉ thị của bạn (là một phần của chế độ xem), bạn đang tạo một khớp nối trực tiếp giữa chế độ xem và mô hình của mình. Bạn cần tách chúng ra bằng cách nối chúng lại với nhau bằng bộ điều khiển.

Nó hoạt động tốt. Tôi không chắc chắn những gì bạn đang làm đó là sai. Đây là một plunk của nó làm việc.

http://plnkr.co/edit/M8omDEjvPvBtrBHM84Am


Bạn có thể cung cấp một ví dụ xin vui lòng
Ngoại lệ

@Exception Bạn có thể đặt mã của bạn trong một fiddle? Tôi có thể xem và xem tại sao mã của bạn không hoạt động và có thể giúp bạn sửa nó.
ganaraj

@Exception đã thêm một plunk làm việc cho thấy mã làm việc.
ganaraj

3
Tôi vừa phát hiện ra một điều: Nếu bạn xác định một phép tiêm trong các tham số chức năng, function($location) { ...nhưng thực tế không đề cập đến $locationbên trong hàm, AngularJS sẽ không thực hiện phép tiêm. Lần duy nhất bạn từng thấy hành vi này là bên trong trình gỡ lỗi.
Walter Stabosz

13
Tôi không chắc chắn tôi đồng ý với nhận xét "ghép" của bạn. Chúng tôi đã kết hợp bộ điều khiển và dịch vụ trên toàn cầu - chúng tôi không thể lập trình thay thế việc triển khai dịch vụ trong thời gian chạy. Có nghĩa là một bộ điều khiển duy nhất có được một dịch vụ duy nhất. Tuy nhiên - các lệnh có cấu hình riêng biệt cho mỗi thẻ trên trang, vì vậy có khả năng chúng tôi kích hoạt dịch vụ khác nhau cho các trường hợp chỉ thị khác nhau. Dường như với tôi điều này là ít tách rời.
anh chàng mograbi

11

Bạn cũng có thể sử dụng dịch vụ $ chích để nhận bất kỳ dịch vụ nào bạn thích. Tôi thấy hữu ích nếu tôi không biết tên dịch vụ trước thời hạn nhưng biết giao diện dịch vụ. Ví dụ, một lệnh sẽ cắm một bảng vào điểm cuối ngResource hoặc nút xóa bản ghi chung tương tác với bất kỳ điểm cuối api nào. Bạn không muốn thực hiện lại chỉ thị bảng cho mọi bộ điều khiển hoặc nguồn dữ liệu.

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)

bây giờ dịch vụ 'ẩn danh' của bạn đã có sẵn. Nếu đó là ngResource chẳng hạn, thì bạn có thể sử dụng giao diện ngResource tiêu chuẩn để lấy dữ liệu của mình

Ví dụ:

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

Tôi đã thấy kỹ thuật này rất hữu ích khi tạo các phần tử tương tác với các điểm cuối API đặc biệt.

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.