2013-06-14 9 views
27

私はAngularJSカスタムディレクティブで最初に試しています。AngularJS - ディレクティブのリンク関数で隔離されたスコープにアクセス

ディレクティブのリンク機能で隔離されたスコープを使用する(または理解している)のに問題があります。ここで

は私のアプリのこの部分のコードです:

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

request view.html

は、リクエストのXML文字列が含まれているviewCtrlの範囲に発表された変数です。

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

生-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> 
IDがcorrecltyときモーダルポップを示している理由を私は理解していない

が、私はそれconsole.log()しようとすると、その値は未定義です。

は、たぶん私は孤立スコープ値(=@)と間違っています。

ありがとうございます。 @を結合させた:)

+0

これは総当て推量ですが、「ID」ため何とか「ID」特別ですDOMの基本部分とAngularは、その理由でディレクティブに正しくマップしません。その属性の名前を変更してより効果的に役立つかどうか試してみましたか? – blaster

+0

あなたがフィドル(jsfiddle.com/plnkr.co)を置くことができれば、多くの助けになります。 –

+0

@blaster:「タイトル」と同じことが起こっていて、DOMの基本的な小道具ではありません。 :) – pdegand59

答えて

34

アイソスコープのプロパティは、リンク機能ですぐに利用できません。あなたは$observeを使用する必要があります:角度が自動的にスコーププロパティidを隔離更新するため

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

あなたのテンプレートが正常に動作します。更新が行われると、テンプレートも自動的に更新されます。

あなただけの文字列を渡している場合は、代わりに単に結合@を使用するのでは一度値を評価することができます

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

あなたは、テンプレートのプロパティを使用したいので、あなたのケースでは、あなたが使用する必要があります@

テンプレートを使用していなかった場合は、属性値が{{}}の–例えば、title="{{myTitle}}"が含まれている場合、その後、@が有用です。 $observeを使用する必要性がより明らかになります。myTitleの値が変更されるたびに、リンク機能が何かをしたいことがあります。

+0

これらの説明をありがとう。また、 'console.log()'を '$ timeout(function(){0}、true);で囲みようとしましたが、' $ scope.id'の値が正しく設定されました。あなたが言ったように、私は '$ attr'オブジェクトの使用について考えましたが、テンプレートにこれらの値が必要なので、 '@'が必要でした。今はすべてが意図どおりに動作しています! :) – pdegand59

+0

双方向バインド属性に対して$ observeを使用しますか?私はそれをログに記録するとき、私は未定義の同じ問題に直面しているが、それはテンプレートの内部で動作します。属性は親スコープのモデルプロパティ(プリミティブとオブジェクト)ですから、 '='バインディングを試しています。 console.logに値を正しく記録させるにはどうすればよいですか? – CMCDragonkai

+0

ところで、モデルプロパティはもちろんAJAXリクエストから生成されるので、開始時には空です。 – CMCDragonkai

9

これは意図的なものであるとコンパイル順序と「@」と「=」の間の差に関係しています。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グーグルグループのリンク...良い読書。 –

0

、上記の回答のどれも実際にも、「=」が一つのキー側面を、言及していない、あなたが、リンク関数内のスコープにアクセスすることができます私には思えません。直接、以下のような、

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

いますが、内部関数でスコープにアクセスすることができ、

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

だから、私には、scope.dataが利用可能な時に時間差があるようです。

関連する問題