2013-06-14 32 views
27

Tôi đang đưa ra một thử đầu tiên tại AngularJS chỉ thị tùy chỉnh.AngularJS - Truy cập phạm vi cô lập trong chức năng liên kết của chỉ thị

Tôi đang gặp sự cố khi sử dụng (hoặc hiểu ...) phạm vi phân lập trong hàm liên kết của chỉ thị.

Đây là mã của phần này của ứng dụng của tôi:

view.html

... 
<raw-data id="request-data" title="XML of the request" data="request">See the request</raw-data> 
... 

request là một biến được công bố trong phạm vi của viewCtrl chứa xml-chuỗi các yêu cầu.

rawData.js

directives.directive('rawData', function() { 

    return { 
     restrict : 'E', 
     templateUrl : 'partials/directives/raw-data.html', 
     replace : true, 
     transclude : true, 
     scope : { 
      id : '@', 
      title : '@', 
      data : '=' 
     }, 
     link : function($scope, $elem, $attr) { 
      console.log($scope.data); //the data is correclty printed 
      console.log($scope.id); //undefined 
     } 
    }; 
}); 

nguyên data.html

<div> 
    <!-- Button to trigger modal --> 
    <a href="#{{id}}Modal" role="button" class="btn" data-toggle="modal" ng-transclude></a> 

    <!-- Modal --> 
    <div id="{{id}}Modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="{{id}}Modal" aria-hidden="true"> 
     <div class="modal-header"> 
      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 
      <h3 id="myModalLabel">{{ title }}</h3> 
     </div> 
     <div class="modal-body"> 
      <textarea class="input-block-level" rows="10">{{ data }}</textarea> 
     </div> 
     <div class="modal-footer"> 
      <!-- <button class="btn" ng-click="toggleTagText('')">{{'cacher'}} l'image</button> --> 
      <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">Fermer</button> 
     </div> 
    </div> 
</div> 

Tôi không hiểu tại sao các ID được correclty hiển thị khi pops phương thức, nhưng khi tôi cố gắng console.log() nó, giá trị của nó là không xác định.

Có thể tôi đã sai với giá trị phạm vi bị cô lập (=@).

Cảm ơn bạn đã đọc. :)

+0

Đây là tổng số phỏng đoán, nhưng là "id" đặc biệt bằng cách nào đó vì "id" một phần cơ bản của DOM và Angular sẽ không ánh xạ nó vào chỉ thị của bạn đúng cho lý do đó? Bạn đã thử đổi tên thuộc tính đó để xem nó có giúp nó hoạt động tốt hơn không? – blaster

+0

Giúp rất nhiều nếu bạn có thể đặt một câu đố (jsfiddle.com/plnkr.co). –

+0

@blaster: Tương tự đã xảy ra với "tiêu đề" và nó không phải là một sự ủng hộ cơ bản của DOM. :) – pdegand59

Trả lời

34

Các thuộc tính phạm vi cách ly được liên kết với @ không có sẵn ngay lập tức trong hàm liên kết. Bạn cần phải sử dụng $observe:

$attr.$observe('id', function(value) { 
    console.log(value); 
}); 

Mẫu của bạn hoạt động đúng vì góc tự động cập nhật cô lập phạm vi tài sản id cho bạn. Và khi cập nhật, mẫu của bạn cũng tự động cập nhật.

Nếu bạn chỉ đi dây, bạn chỉ có thể đánh giá các giá trị một lần thay vì sử dụng @ ràng buộc:

link: function($scope, $elem, $attr) { 
    var id = $attr.id; 
    var title = $attr.title 
    console.log(id, title); 
} 

Tuy nhiên, trong trường hợp của bạn, vì bạn muốn sử dụng các thuộc tính trong mẫu, bạn nên sử dụng @.

Nếu bạn không sử dụng mẫu, thì @ hữu ích khi giá trị thuộc tính chứa {{}} s – ví dụ: title="{{myTitle}}". Sau đó, nhu cầu sử dụng $observe trở nên rõ ràng hơn: hàm liên kết của bạn có thể muốn thực hiện điều gì đó mỗi lần giá trị của myTitle thay đổi.

+0

Cảm ơn bạn đã giải thích các đề tài. Tôi cũng đã cố gắng bọc 'console.log()' với '$ timeout (function() {...}, 0, true);' và giá trị '$ scope.id' được đặt chính xác. Như bạn đã nói, tôi đã nghĩ về việc sử dụng đối tượng '$ attr', nhưng khi tôi cần các giá trị trong mẫu, thì cần phải có '@'. Bây giờ mọi thứ đang hoạt động như dự định! :) – pdegand59

+0

Bạn có sử dụng $ quan sát cho hai thuộc tính được ràng buộc theo cách không? Tôi đang đối mặt với cùng một vấn đề không xác định khi tôi đăng nhập nó, nhưng nó hoạt động bên trong khuôn mẫu. Các thuộc tính là các thuộc tính mô hình (nguyên thủy và các đối tượng) từ phạm vi cha mẹ, vì vậy tôi đã cố gắng ràng buộc '='. Làm thế nào để bạn có được console.log để đăng nhập một cách chính xác giá trị? – CMCDragonkai

+0

Bằng cách này, thuộc tính mô hình tất nhiên được điền từ một yêu cầu AJAX, vì vậy nó trống khi nó bắt đầu. – CMCDragonkai

9

Điều này là cố ý và phải làm với thứ tự biên dịch và sự khác biệt giữa '@' và '='.

Một số đoạn trích từ this Google Groups discussion with input from Misko:

@ and = do very different things. One copies the attribute value (which may be interpolated) and the other treats the attribute value as an expression.

@attrs are not $interpolated until later, so they are not available at link time. If you want to do something with them in the link function you either need to $interpolate yourself manually

+0

+1 cho liên kết nhóm google ... đọc tốt. –

0

tốt, không ai trong số các câu trả lời ở trên thực sự đề cập đến một khía cạnh quan trọng, ngay cả với '=', nó không có vẻ với tôi, bạn có thể truy cập vào phạm vi bên trong chức năng liên kết trực tiếp như sau,

scope: { 
    data: '=', 
}, 
link: function(scope, elem, attrs) { 
    console.debug(scope.data); // undefined 

nhưng bạn có thể truy cập vào phạm vi trong hàm nội bộ,

link: function(scope, elem, attrs) { 
    scope.saveComment = function() { 
     console.debug(scope.data); 

vì vậy dường như với tôi có thể có thời gian trễ khi scope.data có thể có sẵn.

Các vấn đề liên quan