4

私はレイアウトをラップするためのディレクティブをいくつか作成しようとしています。レイアウトから抽象化することができます(それはディレクティブの主な目的の1つです)。置換ディレクティブとフォーム

それでは、私が持っているしたいことは、このようなものです:私はその後、私はそのモデルを確実にしたいこの

app.directive('dialog',()=>{ 
    return { 
    template: '<div class="dialog" ng-transclude></div>', 
    replace: true, 
    transclude: true, 
    restrict: 'E', 
    } 
}) 

ようになり、このための3つの簡単なディレクティブを作成しました

<dialog> 
    <dialog-title></dialog-title> 
    <dialog-body></dialog-body> 
    <dialog-footer></dialog-footer> 
</dialog> 

(dialog-body)で定義されているのは、そのダイアログ上に何らかのフォームが必要であり、フォームの有効/無効に依存しないで無効にできるフッターのナビゲーションボタンがあるためです。​​で

<body ng-controller="MainCtrl"> 
    <p>age: {{age}}</p> 
    <dialog> 
     <p>age: {{age}}</p> 
     <dialog-body> 
     <form name="dialogForm"> 
      <p>age: {{age}}</p> 
      <input ng-model="age" minlength="3"/> 
     </form> 
     </dialog-body> 
     <dialog-footer> 
     <p>age: {{age}}</p> 
     </dialog-footer> 
    </dialog> 
    </body> 

ng-modelダイアログ体の範囲で年齢の変数を作成しますが、それは私がオブジェクトにそれを置くそれまでは他のディレクティブに表示され、MainCtrlに宣言していないでしょう。これは、それがどのように動作するかです:

<body ng-controller="MainCtrl"> 
    <p>age: {{user.age}}</p> 
    <dialog> 
     <p>age: {{user.age}}</p> 
     <dialog-body> 
     <form name="dialogForm"> 
      <p>age: {{user.age}}</p> 
      <input ng-model="user.age" minlength="3"/> 
     </form> 
     </dialog-body> 
     <dialog-footer> 
     <p>age: {{user.age}}</p> 
     </dialog-footer> 
    </dialog> 
    </body> 

とコントローラ:

app.controller('MainCtrl', function($scope) { 
    $scope.user = {age: 1} 
}) 

、私は​​でフォームを入れたいです。これは、ng-modelと同じように、ダイアログボディのスコープでFormControllerを作成する必要があります(またはここではいくつかの違いがあります)。そしてフォームの正当性をチェックするためにダイアログフッタからアクセスする必要があります。

テンプレートにフォームを作成した後、MainCtrlのスコープでformControllerを定義する必要があります。ここでは最初の質問です - FormControllerのインスタンスを作成するにはどうすればいいですか?私は$scope.dialogForm = {$valid: true}はテスト目的のために働くべきであると考えて、ここで私の最後のテンプレートです:

<body ng-controller="MainCtrl"> 
    <p>age: {{user.age}}</p> 
    <p>validity: {{dialogForm.$valid}}</p> 
    <dialog> 
     <p>age: {{user.age}}</p> 
     <p>validity: {{dialogForm.$valid}}</p> 
     <dialog-body> 
     <form name="dialogForm"> 
      <p>age: {{user.age}}</p> 
      <p>validity: {{dialogForm.$valid}}</p> 
      <input ng-model="user.age" minlength="3"/> 
     </form> 
     </dialog-body> 
     <dialog-footer> 
     <p>age: {{user.age}}</p> 
     <p>validity: {{dialogForm.$valid}}</p> 
     </dialog-footer> 
    </dialog> 
    </body> 

ここでの主な問題が来ます。​​でフォームの有効性が変更された場合、それは他のディレクティブには反映されません。どうして?私はここで何が欠けていますか?

私の主な目標は、実際のレイアウトから抽象度を持たせるために、アプリケーションで最も使用されるコンポーネントのディレクティブを持つことです。これは別の方法で行うことができますか?ダイアログ・ボディのフォーム妥当性の変化は、それが他のディレクティブには反映されていない場合はここで

plunk

答えて

3

です。どうして?あなたのディレクティブで

transclude: trueは、新しいスコープを作成し、この場合にはMainCtrlの範囲である親scopeから継承されます。私が知る限り、<form name="dialogForm">を宣言すると、angleはformControllerをdialogBodyのtransludedスコープにバインドします。dialogBodyの場合は$scope.dialogForm = formControllerとなり、それは新しいスコープであるため、他の継承スコープはこの変更を認識しません。

この問題を解決するには、親スコープで共有変数を宣言するか、本質的に同じものであるcontroller as構文を使用します。その後、

<body ng-controller="MainCtrl as vm"> 

vm

<form name="vm.dialogForm"> 
     <p>age: {{vm.user.age}}</p> 
     <p>validity: {{vm.dialogForm.$valid}}</p> 
     <input ng-model="vm.user.age" minlength="3"/> 
    </form> 

にフォームをバインドするには、plunker

はなぜこの仕事をしていますか?すべての新しい継承スコープは親スコープからvmを継承し、formController vm.dialogFormはこの共通変数にバインドされているため、すべての継承スコープにこの変更が反映されるようになります。

関連する問題