2013-08-09 4 views
6

KnockoutJSで「条件付きクリック」バインディングを作成したいとします。基本的にKnockoutで使用するような標準的なクリックバインディングですが、添付された関数を実行するためには条件を満たしている必要があります。 私の場合、最良の選択肢は、カスタムバインディングハンドラを作成し、それが許可されていれば標準のクリックバインディングを呼び出すことです。カスタムバインディングからKnockoutのクリックバインディングを呼び出す

ko.bindingHandlers.safeClick = { 
    'init': function(element, valueAccessor, allBindingsAccessor, context) { 
     $(element).click(function() { 
      if(mycondition == true) { 
       // call the standard click binding here -> this is the part I don't know 
      } 
     }); 
    } 
} 

標準のクリックバインディングをこのカスタムバインディングに置き換えたいとします。したがって、クリックバインディングを正しい方法で呼び出すことが重要です。そのため、HTMLで提供されるすべてのパラメータが関数に渡されます。たとえば:あなたはカスタムバインディングで欠落している部分で私を助けることができれば

<a href="#" data-bind="click: basevm.gotopage.bind($data, '#homepage')">Home</a> 
<a href="#" data-bind="click: itemvm.activateItem">Activate</a> 

これらは、私はそれを非常に感謝し

<a href="#" data-bind="safeClick: basevm.gotopage.bind($data, '#homepage')">Home</a> 
<a href="#" data-bind="safeClick: itemvm.activateItem">Activate</a> 

で交換する必要があります。

答えて

11

ここで結着クリックを委任する正しい方法は以下の通りです:

  • 元の機能を使用してください(例:valueAccessor()を使用)
  • 新しいvalueaccessor関数を作成します。この関数では、条件を含む新しい関数が返され、元の関数が呼び出されます。そして、この新しい値のアクセッサーをclickバインディングに渡します。

だからあなたsafeClickは次のようになります。

ko.bindingHandlers.safeClick = { 
    'init': function (element, valueAccessor, allBindingsAccessor, 
         viewModel, bindingContext) { 
     var originalFunction = valueAccessor(); 
     var newValueAccesssor = function() { 
      return function() { 
       if (mycondition == true) 
        //pass through the arguments 
        originalFunction.apply(viewModel, arguments); 
      } 
     } 
     ko.bindingHandlers.click.init(element, newValueAccesssor, 
      allBindingsAccessor, viewModel, bindingContext); 
    } 
} 

デモJSFiddle

これは最初のクリックで機能し、クリックイベントを手動で購読したりjQueryでトリガする必要はありません。

+0

このメソッドは、条件をHTMLコードのノックアウト観測値として渡すことを前提としています。私はこれをしたくない。代わりに、要素をクリックするたびにJavaScriptコードで条件を手動でチェックしたいと考えています。あなたはそれを行う方法についてアドバイスをしていますか? –

+0

'if(ko.utils.unwrapObservable(allBindingsAccessor()。condition))'の代わりに、あなたが望むものを書くことができます。リンクがクリックされるたびに評価されます。私は私のデモjsfiddleのために観察可能な条件が必要でした。 http://jsfiddle.net/w7nKB/2/ – nemesv

+0

通常のクリックバインドとこのカスタムバインディングとの間の問題を説明するために、このフィドル(http://jsfiddle.net/Ed8Fc/)を作成しました。私は、クリックイベントを引き起こしたDOM要素にアクセスする必要があります。通常のクリックバインドでこれはOKですが、safeClickバインディングではブラウザコンソールにエラーが報告されています。 –

1

あなたは次のようにそれを呼び出すことができます。

ko.bindingHandlers.click.init(element, valueAccessor, allBindingsAccessor, context); 

EDIT: あなたがイベントに初めてをクリックして呼び出すmannualyことができます。

ko.bindingHandlers.safeClick = { 
    'init': function(element, valueAccessor, allBindingsAccessor, context) { 
     $(element).click(function() { 
      if(mycondition == true) { 
       ko.bindingHandlers.click.init(element, valueAccessor, allBindingsAccessor, context); 
      } 
     }); 
     if(mycondition == true) { 
      $(element).trigger('click'); 
     } 
    } 
} 
+0

ウェブを検索しているうちに、すでにこの記事が表示されていました。残念なことに、これはアンカー要素を2回クリックしたときにのみ機能することがわかりました。私のソリューションは、ユーザーが最初にクリックしたときから動作する必要があります。 –

+0

更新情報を参照してください。 –

関連する問題