Knockoutjs実戦開発:制御サブバインド(control descendant bindings)
16664 ワード
前の記事では、カスタムバインドを作成する方法について説明しましたが、今日はサブバインド(control descendant bindings)を制御する方法について学び続けます.この前に、この機能は比較的高度であり、通常、Knockoutjsを使用してアプリケーションを作成するときに必ず使用するわけではありません.
デフォルトでは、バインドはバインドされたelement要素にのみ機能します.しかし、このバインドがバインドされたelementのすべてのサブelementに役立つようにするにはどうすればいいですか?bindingをカスタマイズするとき、Knockoutjsは彼のサブ要素をバインドしないことを教えて、このように私たちが定義したバインドは私たちの好きな方法で任意にバインドすることができます.init関数で
一、制御がサブバインディングに作用するかどうか
非常に簡単な例を挙げて、
このバインディングはUIで使用できます.
二、サブバインディングに追加の値を提供する
バインドを定義します:
私たちが見たように、extend関数を使用して追加の属性のクローンを生成します.これは私たち自身の要素の値に影響しません.そのため、彼の同レベルの要素にも影響しません.それは字要素にのみ影響します.
次に、上記のカスタムバインドを使用します.
三、コンテキスト階層に追加の水平バインドを追加する
たとえばwith、foreachバインドは、対応する水平バインドを同レベルのコンテキスト階層でバインドできます.これにより、サブバインドで$parent、$parents、$root、$parentContextを使用して外部のプロパティを呼び出すことができます.この機能をカスタムバインドで使用したい場合は、上記の例の
デフォルトでは、バインドはバインドされたelement要素にのみ機能します.しかし、このバインドがバインドされたelementのすべてのサブelementに役立つようにするにはどうすればいいですか?bindingをカスタマイズするとき、Knockoutjsは彼のサブ要素をバインドしないことを教えて、このように私たちが定義したバインドは私たちの好きな方法で任意にバインドすることができます.init関数で
{ controlsDescendantBindings: true }
を返すだけです一、制御がサブバインディングに作用するかどうか
非常に簡単な例を挙げて、
allowBindings
というバインド名をカスタマイズします.そうすれば、彼の値がtrueであれば、サブバインドを行います.彼の値がfalseの場合、サブバインドは何の役にも立たない.1 <script type="text/javascript">
2 ko.bindingHandlers.allowBindings = {
3 init: function (elem, valueAccessor) {
4 // Let bindings proceed as normal *only if* my value is false
5 var shouldAllowBindings = ko.utils.unwrapObservable(valueAccessor());
6 return { controlsDescendantBindings: !shouldAllowBindings };
7 }
8 };
9 </script>
このバインディングはUIで使用できます.
1 <div data-bind="allowBindings: true">
2 <!-- This will display Replacement, because bindings are applied -->
3 <div data-bind="text: 'Replacement'">Original</div>
4 </div>
5
6 <div data-bind="allowBindings: false">
7 <!-- This will display Original, because bindings are not applied -->
8 <div data-bind="text: 'Replacement'">Original</div>
9 </div>
二、サブバインディングに追加の値を提供する
バインドを定義します:
withProperties
、その属性は彼のすべてのサブバインドによって得ることができます: 1 <script type="text/javascript">
2 ko.bindingHandlers.withProperties = {
3 init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
4 // Make a modified binding context, with a extra properties, and apply it to descendant elements
5 var newProperties = valueAccessor(),
6 innerBindingContext = bindingContext.extend(newProperties);
7 ko.applyBindingsToDescendants(innerBindingContext, element);
8
9 // Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice
10 return { controlsDescendantBindings: true };
11 }
12 };
13 </script>
私たちが見たように、extend関数を使用して追加の属性のクローンを生成します.これは私たち自身の要素の値に影響しません.そのため、彼の同レベルの要素にも影響しません.それは字要素にのみ影響します.
次に、上記のカスタムバインドを使用します.
1 <div data-bind="withProperties: { emotion: 'happy' }">
2 Today I feel <span data-bind="text: emotion"></span>. <!-- Displays: happy -->
3 </div>
4 <div data-bind="withProperties: { emotion: 'whimsical' }">
5 Today I feel <span data-bind="text: emotion"></span>. <!-- Displays: whimsical -->
6 </div>
三、コンテキスト階層に追加の水平バインドを追加する
たとえばwith、foreachバインドは、対応する水平バインドを同レベルのコンテキスト階層でバインドできます.これにより、サブバインドで$parent、$parents、$root、$parentContextを使用して外部のプロパティを呼び出すことができます.この機能をカスタムバインドで使用したい場合は、上記の例の
bindingContext.extend()
ではなく、bindingContext.createChildContext(someData)。 , viewmodel someData, $parentContext bindingContext。 ko.utils.extend
を してサブコンテキストを します. 1 <script type="text/javascript">
2 ko.bindingHandlers.withProperties = {
3 init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
4 // Make a modified binding context, with a extra properties, and apply it to descendant elements
5 var newProperties = valueAccessor(),
6 childBindingContext = bindingContext.createChildContext(viewModel);
7 ko.utils.extend(childBindingContext, newProperties);
8 ko.applyBindingsToDescendants(childBindingContext, element);
9
10 // Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice
11 return { controlsDescendantBindings: true };
12 }
13 };
14 </script>
これにより、カスタムwithPropertiesをネストで でき、$parentContextを して コンテキストを できます.1 <div data-bind="withProperties: { displayMode: 'twoColumn' }">
2 The outer display mode is <span data-bind="text: displayMode"></span>.
3 <div data-bind="withProperties: { displayMode: 'doubleWidth' }">
4 The inner display mode is <span data-bind="text: displayMode"></span>, but I haven't forgotten
5 that the outer display mode is <span data-bind="text: $parentContext.displayMode"></span>.
6 </div>
7 </div>
バインドコンテキストと サブバインドを することで、 のカスタムバインドメカニズムを する で なツールがあります.