2017-02-15 5 views
0

現在、コンポーネントを使用するために、角度1.5.8のアプリケーションでいくつかのコードをリファクタリングしています。変数の前に呼び出される角型コンポーネントのトリガメソッド

(このガイドのいくつかの手順に非常に似ています:https://teropa.info/blog/2015/10/18/refactoring-angular-apps-to-components.html) 基本的なケースが正しく動作しています。

しかし、コンポーネントを変数を更新する必要があるときに問題が発生し、関数(両方とも親からバインドされています)を呼び出します。この場合、関数呼び出しは、変数がバインドされる前に発生しているようです。したがって、メソッドが親に対して実行されても、変数の古い内容が使用されています。

メソッドが実行される前に変数が更新されていることを確認するにはどうすればよいですか?

下記のコードでは、reset()関数の2行です。

angular.module('searchfieldComponent', []) 

.component('searchfieldComponent', { 
    templateUrl: "/js/common/components/searchfield.component.tpl.html", 
    bindings: { 
     labelText: '@', 
     searchText: '=', 
     searchCallback: '&' 
    }, 
    controllerAs: "vm", 
    controller: [function() { 

     var vm = this; 

     vm.search = function() { 
      vm.searchCallback(); 
     } 

     vm.reset = function() { 
      vm.searchText = null; 
      // When the method bound to searchCallback executes in the parent, 
      // the variable bound to searchText has not yet been set to null 
      // it is still the old value. 
      vm.searchCallback(); 
     } 
    }] 
}); 
+0

オブジェクトを使用してコンポーネント間でデータを渡した後、そのプロパティを変更するとどうなりますか? 'searchData: '="; /*...*/ vmのように。searchData.text = null' – raina77ow

+0

これは機能します。ありがとう!私はこれがいつも同じオブジェクトだからだと思うので、タイミングの問題をこのように避けてください。答えとして投稿しても構いませんが、最適な解決策ではなく、回避策になるようオブジェクトをラップすることを検討します。より良い答えが現れなければ、私は数日後にそれを受け入れます。 – PMBjornerud

答えて

1

問題への鍵は、この行...

vm.searchText = null; 

が...何を考えています。確かに、それは '子'スコープに設定された値を更新します。しかし、正確に '親'値が更新されると、

標準のプロトタイプ継承メカニズムを介して親スコープ変数と子スコープ変数を直接リンクすることはできません。 child.fooプロパティをクエリする間、名前解決はその値をchild.__proto__.fooに置き換えます。しかし、に何か何かを割り当てるとすぐに、プロトタイプのプロパティはシャドウされます。

AngularJSは商標摘要のアプローチでこの刑務所を退去させることができます。ダイジェスト段階では、子スコープへの変更が親スコープへの変更に伝わります(詳細はthis answerをチェックしてください)。しかし、それに基づいて何かをしたいのであれば、あなたは困っています。

救済策とは何ですか?あなたはvm.searchDataに格納されている基準を変更することはありませんように... ...ではなく、このような、プリミティブの使用共有オブジェクト

bindings: { 
    labelText: '@', 
    searchData: '=', 
    searchCallback: '&' 
} 

// then, in vm methods 
vm.searchData.searchText = 'anything'; 

- あなたは:私はコメントで提案のだ1は最も知られており、いずれかを試してみましたです代わりにそのプロパティを増やします。両方のコンポーネントが同じ場所で「見て」いるので、明らかに両方が変更を参照します。


より良い考え方は全体的にsearchfieldComponentの構造を再考するかもしれません。親のスコープがsearchTextの値を知っている必要があるのはなぜか分かりません。 Angularコンポーネントの全体のポイントは、ややゆるやかに定義されたディレクティブを、厳密な入出力セットを持つエンティティに変換しています。

一般的なsearchFieldについては、あらかじめ定義されたdefaultValueを入力することをお勧めします(入力のため、'>'のマークが付いています)。しかし、何かを変更する必要があるときは、コンポーネントにchangedValueを出力関数(searchCallbackに似ていますが、より良い名前を付けて)で出力させ、この値をこの関数にパラメータとして渡します。

+0

私のコンポーネントが小さすぎるのでしょうか?他の手段でコードが重複しないようにするには、コンポーネントを使用する必要はありません。ここでは、親だけがsearchTextのコンテキストを知っています。コンポーネントの場合は、コンテキストを持たない単なる文字列です。このコンポーネントは、小さなコードの共通コード(レイアウト、キー検出の入力、およびテキストを消去するボタン)を提供します。 – PMBjornerud

+0

それは問題ですが、なぜですか?このコンポーネントが正しくデカップリングされるためには、親コンポーネントと緊密に結合されたコンポーネントだけでなく、コンポーネントとしての入力と出力が必要です。 – raina77ow

関連する問題