3

私が取り組むアプリケーションでは、ユーザーはドロップダウンからフォームタイプを入力し、ボタンをクリックしたときに呼び出されるディレクティブによって新しいフォームを作成できます。作成されたフォームは実際にはスコープにコンパイルされ、DOM内のラッパー要素に追加される別のディレクティブです。新しいディレクティブを作成するclickディレクティブのコードは次のとおりです。データオブジェクト内に新しいディレクティブを作成するAngularJsディレクティブ

(function(){ 
'use strict'; 

//on 'add new rule' btn click, a new form is created 

function createRuleForm($compile){ 

    function linkFn(scope, element, attrs){ 

     function onClickAddForm(){ 

      var type = scope.rcCtrl.ruleType; 
      var newDirective = angular.element('<rule-form type="'+type+'"></rule-form>'); 
      var formWrap = document.querySelector('.edit-rc__div--rf-wrapper'); 

      angular.element(formWrap).append(newDirective); 
      $compile(newDirective)(scope) 

     } 

     element.bind('click', onClickAddForm) 
    } 

    return{ 
     restrict: 'A', 
     link: linkFn 
    } 
} 

angular.module('ganeshaApp') 
.directive('createRuleForm', [ 
    '$compile', 
    createRuleForm 
]) 
})(); 

ユーザーが一度に複数のフォームで作業、およびそれらのフォームを保存し、編集できるようにする必要があるとして作成されたそれぞれの新しいフォームは、分離株のスコープを持っています。 'type'は属性として新しいフォームに渡されます。これは、クリック時に作成される新しい指令です。

(function(){ 
'use strict'; 

function ruleForm(ModalService, CurrentDateService, SaveRule, RULE_PHRASE){ 

    var index = 0; 

    //directive controller 
    function RuleFormCtrl($scope, $element, $attrs){ 

     var rfCtrl = this; 

     //values 
     rfCtrl.ruleType = $scope.$parent.rcCtrl.ruleType; 
     rfCtrl.ruleTitle = 'L_' + $attrs.type + index; 
     rfCtrl.phrase = RULE_PHRASE[$attrs.type]  
     rfCtrl.fullDate = CurrentDateService.getCurrentDate() 

     //functions 
     rfCtrl.saveOneRule = saveOneRule; 
     rfCtrl.closeRule = closeRule; 

     //saves one rule on click of save button or on timeout 
     function saveOneRule(){ 

     rfCtrl.html = $element.find('.edit-rf__div--textdiv').html(); 

      var ruleObject = { 
       'index' : index, 
       'ruleText' : rfCtrl.ruleText, 
       'ruleTitle' : rfCtrl.ruleTitle, 
       'ruleType' : rfCtrl.ruleType, 
       'typePhrase' : rfCtrl.phrase, 
       'html' : rfCtrl.html, 
       'fullHtml' : rfCtrl.phrase + rfCtrl.html 
      } 

      SaveRule.pushRule(ruleObject) 
      $scope.ruleForm.$setPristine(); 
      index++; 
     } 

     function closeRule(){ 

      if($scope.ruleForm.$dirty){ 

       var modal = { 
        "mssg" : 'You have unsaved changes to this rule. Would you like to save them before closing?', 
        "confirm" : 'Yes, please.', 
        "reject" : 'No, thank you.' 
       } 

       ModalService.openModal(modal). 
       then(function(res){ 
        console.log(res) 
        saveOneRule(); 
        $element.remove(); 
       }).catch(function(err){ 
        console.log(err) 
       }) 
      }else{ 
       $element.remove(); 
      } 
     } 

    } 


    return{ 
     restrict: 'E', 
     replace: true, 
     scope: {}, 
     templateUrl: 'modules/edit/edit-create/ruleForm.html', 
     controller: RuleFormCtrl, 
     controllerAs: 'rfCtrl' 
    }; 

} 

angular.module('ganeshaApp') 
.directive('ruleForm', [ 
    'ModalService', 
    'CurrentDateService', 
    'SaveRule', 
    'RULE_PHRASE', 
    ruleForm 
]); 

})(); 

フォームが保存されると、それはビューのスクロール可能なリストに追加されます。

初めてフォームを作成して保存する場合は、ここですべてうまくいきます。私が抱えている難しさは、ユーザーがビューのフォームのリストからフォームを開く必要があるときです。新しいディレクティブに渡されるデータが単純な文字列 'ruleType'である新しいフォームを作成するのとは異なり、完成したフォームのディレクティブを作成するには、保存されたオブジェクトデータを新しいディレクティブに渡す必要があります。

クリックディレクティブがデータと一緒にパッケージ化する必要のある要素ディレクティブを作成するこのような状況に慣れている人はいないでしょうか?

+1

にアクセスすることができます私には正しい感じがしますが、私が正確に理解しているかどうかはわかりません。なぜあなたは、データとng-repeatを使って、フォーム入力とバインディングを動的に行うのではなく、コンパイルするだけですか?あなたがplunkr/fiddleを持っているなら、私はそれを詳しく見るか、より良いアプローチを提案することができます –

+0

返事、ダニエルに感謝します。説明が少し分かりにくいので、私の謝罪。私はng-repeatを使うことを考えましたが、このユースケースにはうまく収まらないようです。ユーザーは、自分が作業している「ルール」のリストを表示したい(これはビュー内のng-repeatスクロール可能なリストです)。しかし、それらは一度に1つだけ編集することも、2つを編集することもできます。彼らの視点を常に制御したいと思っています。しかし、今考えてみると、おそらくフィルターが解決策を提供するでしょう。私は後で泥棒を手に入れることができるかどうかを見ます。 – hughesjmh

+1

偉大な、ここに戻って私を見てみましょう。あなたのコメントによると、私はそれを制御するためにフィルタを使用したいと思います。あなたが解決策を展開すると、上記の道を行くことはかなり混乱するでしょう –

答えて

1

あなたはちょうどあなたのルールフォームディレクティブのスコープは、その探していることを確認してくださいあなたは要素をコンパイルするとき、あなたのスコープにデータを追加することができ、その後、あなたのhtmlに

var type = scope.rcCtrl.ruleType; 

var data = {'your': 'data', 'object': 'here'}; 

//add the data to the scope so that the child element has access to it 
scope.data = data; 

//pass the data into your rule-form directive using whatever attribute you declared 
var newDirective = angular.element('<rule-form type="'+type+'" form-data="data"></rule-form>'); 
var formWrap = document.querySelector('.edit-rc__div--rf-wrapper'); 

angular.element(formWrap).append(newDirective); 
$compile(newDirective)(scope) 

を、それを参照する必要がありますフォーム - データ属性は

return{ 
    restrict: 'E', 
    replace: true, 
    scope: { 
     formData: '=' 
    }, 
    templateUrl: 'modules/edit/edit-create/ruleForm.html', 
    controller: RuleFormCtrl, 
    controllerAs: 'rfCtrl' 
}; 

次にRuleFormCtrlに、あなたはこれをqをしませんFORMDATA

function RuleFormCtrl($scope...){ 
    var data = $scope.formData; 
} 
+0

ありがとう、ツイッチ!それは働いていますが、少し修正を加えなければなりませんでした。オブジェクトがコンパイルされているディレクティブ内のscope.rcCtrl.dataオブジェクトの場合、新しいディレクティブで$ scope。$ parent.rcCtrl.dataをスコープとして使用してアクセスする必要があります。 – hughesjmh

関連する問題