30

次のようなカスタム タグを作成しようとしています。

<mytag type="Big" />

type は、コンポーネントにバインドされる属性です。以下に示すように、ラベルにテキストを設定するようにします。

<label>{{type}}</label>

... (その他のコンポーネント)...

ドキュメントにあるように、デフォルトのタイプを設定するコントローラーがあります。

$scope.type = "Small";

そのため、属性タイプなしでタグを使用しても設定されます。

ディレクティブを使用してバインドしようとしています:

angular.module('TestPage',[])
      .directive('mytag',function() {
          return {
              restrict: 'E',
              templateUrl: 'component.html',
              scope: {
                  type: '='
              }
          }
      });

コンポーネント テンプレート (ng-app="TestPage") に適切な ng-app 設定があることに注意してください。

私の問題は、型へのバインディングが実際には何もバインドしていないように見えることです。

ディレクティブを使用して変数をコンポーネントにバインドする方法に関するドキュメントを読みました。ドキュメントによると、スコープ内でそのようなバインディングを行うことができます。スコープには、「分離スコープ」(???) と呼ばれるものを作成する「オブジェクト ハッシュ」(それが何であれ!) を含めることができるようです。このようなスコープは、次の方法で「ローカル プロパティ」を表すことができます。

@ または @attr - ローカル スコープ プロパティを DOM 属性にバインドします。DOM 属性は文字列であるため、結果は常に文字列になります。属性名が指定されていない場合、ローカル名と属性名は同じです。指定されたスコープのウィジェット定義: { localName:'@myAttr' } の場合、ウィジェット スコープ プロパティ localName は、hello {{name}} の補間値を反映します。name 属性が変更されると、ウィジェット スコープの localName プロパティも変更されます。名前は、(コンポーネント スコープではなく) 親スコープから読み取られます。

は???バインディングの適切な構文とこれは何の関係があるのでしょうか?

= または =expression - ローカル スコープ プロパティと親スコープ プロパティの間の双方向バインディングを設定します。属性名が指定されていない場合、ローカル名と属性名は同じです。スコープのウィジェット定義: { localModel:'=myAttr' } を指定すると、ウィジェット スコープ プロパティ localName は、親スコープの parentModel の値を反映します。parentModel への変更は localModel に反映され、localModel の変更は parentModel に反映されます。

すみません?ここで何が言われていますか?

& または &attr - 親スコープのコンテキストで式を実行する方法を提供します。属性名が指定されていない場合、ローカル名と属性名は同じです。指定されたスコープのウィジェット定義: { localFn:'increment()' } の場合、分離スコープ プロパティ localFn は、increment() 式の関数ラッパーを指します。式を介してisolateスコープから親スコープにデータを渡すことが望ましい場合がよくあります。これは、ローカル変数名と値のマップを式ラッパーfnに渡すことで実現できます。たとえば、式が increment(amount) の場合、localFn を localFn({amount: 22}) として呼び出して金額の値を指定できます。

今、私は完全に混乱しています!ウィジェットタグと、バインドを行うために私が書かなければならない何らかの関連関数がありますか??? 私が欲しいのは、値をラベルタグにバインドすることだけです!

上記のテキストをドキュメント ( http://docs.angularjs.org/guide/directive ) からコピーして強調しておきます。この doco は古い UNIX ドキュメントのように読めます。システムを既に知っている人にとっては非常に便利ですが、本当の専門知識を身につけようとしている初心者にはあまり役に立ちません。AngularJS で簡単なタスクを実行する方法を示すすべてのチュートリアルがあるのに (おもちゃのアプリには最適ですが、私が構築したい種類のクライアント側アプリケーションにはあまり適していません)、なぜより高度なものがないのでしょうか?

さて、私がもっと建設的になる時間です。

このドキュメントで説明するのが非常に難しいさまざまなバインディングを実行する方法について、誰かが素敵で簡単な例を提供してくれませんか? これらのスコープ ステートメントの適切な構文を示す例と、カスタム タグに追加されている属性に戻る方法の正確な説明 (平易な英語で) ???

何卒ご理解とご協力を賜りますようお願い申し上げます。

4

2 に答える 2

66

私も最初にAngularを始めたとき、このドキュメントに少し苦労しましたが、あなたのために物事を明確にするよう試みます. まず、このscopeプロパティを使用すると、「分離スコープ」が作成されます。つまり、親スコープからプロパティを継承しないため、スコープ内での衝突について心配する必要はありません。

現在、「@」表記は、属性で評価された値がディレクティブのスコープに自動的にバインドされることを意味します。そのため、文字列「bar」を保持する<my-directive foo="bar" />というプロパティを持つスコープになります。foo次のようなこともできます<my-directive foo="{{bar}}"そして、評価された値は{{bar}}スコープにバインドされます。属性は常に文字列であるため、この表記法を使用すると、スコープ内のこのプロパティの文字列が常に終了します。

「=」表記は基本的に、オブジェクトをディレクティブに渡すためのメカニズムを提供します。これは常にディレクティブの親スコープから取得されるため、この属性には{{}}. したがって、持っている場合は、ディレクティブのスコープのプロパティで、ディレクティブに含まれる<my-directive foo="bar" />ものをすべてバインドします。スコープ内で行った変更は親スコープに反映され、その逆も同様です。$scope.barfoofoobar

「&」表記も他のものほど使用していないので、それらの 2 つほどよく知りません。私が理解していることから、親スコープのコンテキストから式を評価できます。したがって、次のようなものがある場合<my-directive foo="doStuff()" />、ディレクティブ内で scope.foo() を呼び出すたびに、ディレクティブの親スコープで doStuff 関数が呼び出されます。これでできることは他にもたくさんあると思いますが、私はそのすべてに精通しているわけではありません。たぶん、他の誰かがこれをより詳細に説明できるでしょう。

シンボルだけがスコープに設定されている場合は、属性と同じ名前を使用してディレクティブ スコープにバインドします。例えば:

scope: {
   foo1: '@',
   foo2: '=',
   foo3: '&'
}

ディレクティブを含める場合、属性 foo1、foo2、および foo3 が必要です。属性名とは異なるスコープ内のプロパティが必要な場合は、シンボルの後に指定できます。したがって、上記の例は次のようになります

scope: {
   foo1: '@bar1',
   foo2: '=bar2',
   foo3: '&bar3'
}

ディレクティブを含める場合、属性 bar1、bar2、および bar3 が必要であり、これらはそれぞれプロパティ foo1、foo2、および foo3 の下のスコープにバインドされます。

これが役立つことを願っています。私の答えを明確にするために、遠慮なく質問してください。

于 2012-10-23T14:53:04.487 に答える
33

あなたはかなり近い..

app.directive('mytag',function() {
    return {
        restrict: 'E',
        template: '<div>' +
            '<input ng-model="controltype"/>' + 
            '<button ng-click="controlfunc()">Parent Func</button>' + 
            '<p>{{controlval}}</p>' + 
         '</div>',
        scope: {
            /* make typeattribute="whatever" bind two-ways (=)
            $scope.whatever from the parent to $scope.controltype
            on this directive's scope */
            controltype: '=typeattribute',
            /* reference a function from the parent through
               funcattribute="somefunc()" and stick it our
               directive's scope in $scope.controlfunc */
            controlfunc: '&funcattribute',
            /* pass a string value into the directive */
            controlval: '@valattribute'
        },
        controller: function($scope) {                  
        }
    };
});

  <div ng-controller="ParentCtrl">
       <!-- your directive -->
       <mytag typeattribute="parenttype" funcattribute="parentFn()" valattribute="Wee, I'm a value"></mytag>
       <!-- write out your scope value -->
       {{parenttype}}
  </div>


  app.controller('ParentCtrl', function($scope){ 
       $scope.parenttype = 'FOO';
       $scope.parentFn = function() {
           $scope.parenttype += '!!!!';
       }
  });

魔法は、主にscope:ディレクティブ定義の宣言にあります。そこにscope: {}あると、スコープが親から「分離」されます。つまり、それは独自のスコープを取得します...それがなければ、親のスコープを使用します。マジックの残りの部分は、スコープのプロパティにあります: scope: { 'internalScopeProperty' : '=externalAttributeName' }... ここで、=は双方向のバインディング シナリオを表します。これを に変更する=@、文字列を属性としてディレクティブに渡すことができることがわかります。&は、親スコープのコンテキストから関数を実行するためのものです。

それが役立つことを願っています。


編集:ここに作業中のPLNKRがあります

于 2012-10-23T14:52:08.983 に答える