2017-10-28 12 views
1

フォームを動的に生成するシステムを作成しようとしています。私は、入力IDから入力フィールドに関するメタデータを検索し、そのフィールドのテンプレートを生成する指令を作成しました。入力は正常に機能しますが、フォームはそれが存在することを認識しません。 $ validなどの計算には影響しません。コンパイルとリンクの間には何か神秘的なことが起こっているので、フォームは入力を認識しますか?フォームがカスタム入力ディレクティブを認識しない

ここでは単純化されたコードです: にこの動作を参照:あなたが考えている神秘的なものは「適用範囲」であるPlunker

<form name="myForm"> 
    works: <input type="text" ng-model="model.works" required></input> 
    <div ng-repeat="inp in inputList"> 
     broken: <my-component info="inp"></my-component> 
    </div> 
    form valid: {{myForm.$valid}} 
</form> 

app.controller('MainCtrl', function($scope) { 
    $scope.model = { 
    works:'works', 
    broken:'broken', 
    }; 
    $scope.inputList = [ 
    {id:'broken'}, 
    ]; 
}); 

app.directive('myComponent', function($compile) { 
    return { 
    restrict: 'E', 
    scope: { 
     'info': '=' 
    }, 
    link: function($scope, $element, $attrs) { 
     var html = '<input type="text" ng-model="model.'+ $scope.info.id +'" required></input>'; 
     $scope = $scope.$parent.$parent; 
      //^this hack makes the model work, but form still not attached 
     var el = $compile(html)($scope); 
     $element.replaceWith(el); 
    } 
    }; 
}); 

答えて

0

が。 AngularJS「スコープ」は、モデル、ビュー、およびコントローラーを結合するものです。投稿されたコードには、3つの異なるスコープが考慮されます。 "MainCtrl"スコープこれを「scope01」と呼ぶことにします。 "ng-repeat"は各反復に対して新しいスコープを作成します。配列に1つの項目しかないので、この 'scope02'と呼ぶことにします。最後に、あなたの指示にisolate scopeがあります。これを「scope03」と呼ぶことにします。

"MainCtrl"コントローラscope01に戻るには、ディレクティブ内の変数が2つのスコープを通過する必要があります。これはあなたのハックが2つの "$親"コールを必要とする理由です。 "myForm"オブジェクトは 'scope01'にあります。 'scope02'に継承されますが、 'scope03'に渡す必要があります。パラメータを二重にバインドするか、イベントを使用して変更を入力にブロードキャストすることで、 'scope01'への変更をバブルアップする必要があります。あなたのディレクティブで

<my-component info="inp" form-ref="myForm"> 

:ここ

は、パラメータと、二重結合を使った例です

var directive = { 
restrict: 'E', 
scope: { 
    'info': '=', 
    'formRef': '=' 
}, 
link: function(scope, element, attributes) { 
    //You may want to wrap the following in a watch: 
    formRef.$valid = myService.isValid(scope.info);// myService checks if input is valid and returns true or false 
} 
}; 
+0

これは、各入力上書きフォームを持たないでしょうか?$ valid? – Dirigible

+0

はい、ほとんどの場合、スコープ間の通信方法の例を示していました。フォームオブジェクトにアクセスできます。そのアクセスをどのようにして行うのかは、あなた次第です。この猫には多くの方法があります。 – Drellgor

0

誰がこのに実行される場合には、私は、解決策を見つけた:

var el = $compile(html)($scope.$parent, function(_el) { 
     $element.replaceWith(_el); 
    }); 

Plunker

関連する問題