2012-07-11 4 views
5

をフェードアウトした後、フェードインは、私は3つのラジオボタンのセットを持って言う:ユーザーが最初のラジオボタン(マイン/自分を)選択するとKnockoutJS:何か他

<div> 
    <label> 
     <input type="radio" name="Who" value="Myself" 
      checked="@isMyselfChecked" data-bind="checked: who" /> 
     Mine 
    </label> 
    <label> 
     <input type="radio" name="Who" value="MemberId" 
      checked="@isMemberIdChecked" data-bind="checked: who" /> 
     I know the member's ID 
    </label> 
    <label> 
     <input type="radio" name="Who" value="MemberUrl" 
      checked="@isMemberUrlChecked" data-bind="checked: who" /> 
     I know the member's URL 
    </label> 
</div> 

、追加の入力は必要ありません。しかし、第二または第三、追加の入力を選択する際に、が必要です。

<div> 
    <input type="text" name="MemberId" placeholder="Enter Member ID" 
     data-bind="toggleWho: who()" style="display: none" /> 
    <input type="text" name="MemberUrl" placeholder="Enter Member URL" 
     data-bind="toggleWho: who()" style="display: none; width: 450px;" /> 
</div> 

ちょうど依存テキストボックスにdata-bind="visible: who() === '[MemberId|MemberUrl]'"を持っているために十分に簡単です。しかし、フェードイン/アウトトランジションを追加したい場合はどうすればよいですか?

ノックアウトサイトからカスタムfadeVisiblebindingHandlerを試しましたが、どのように動作するのか理解しています。しかし、これは同時にフェードインしてテキストボックスをフェードインします。ラジオ'MemberId'を選択し、ユーザーが'MemberUrl'ラジオを選択し、私はMemberUrlテキストボックスがフェードイン前をフェードアウトするMemberIdテキストボックスを希望される場合。

以下は「私が今持っているものであり、それは動作しますが、私はドンそれが最適だとは思わない。前の要素がフェードアウトされるまでフェードインを実行しないようにノックアウトする方法は他にありますか?別のko.observale、またはおそらくko.computedが必要ですか?

var viewModel = { 
    fadeSpeed: 150, 
    who: ko.observable($('input[type=radio][name=Who]:checked').val()) 
}; 

ko.bindingHandlers.toggleWho = { 
    init: function (element, valueAccessor) { 
     var value = valueAccessor(); 
     var unwrapped = ko.utils.unwrapObservable(value); 
     if (unwrapped === element.name) 
      $(element).show(); 
    }, 
    update: function (element, valueAccessor) { 
     var value = valueAccessor(); 
     var unwrapped = ko.utils.unwrapObservable(value); 

     // when selected value is myself, fade out the visible one, if any 
     if (unwrapped === 'Myself') { 
      $('input[type=text][name=MemberId]:visible') 
       .fadeOut(viewModel.fadeSpeed); 
      $('input[type=text][name=MemberUrl]:visible') 
       .fadeOut(viewModel.fadeSpeed); 
     } 

      // when selected value is memberid, may need to fade out url first 
     else if (unwrapped === 'MemberId') { 
      if ($('input[type=text][name=MemberUrl]:visible').length > 0) { 
       $('input[type=text][name=MemberUrl]:visible') 
        .fadeOut(viewModel.fadeSpeed, function() { 
         $('input[type=text][name=MemberId]') 
          .fadeIn(viewModel.fadeSpeed); 
        }); 
      } else { 
       $('input[type=text][name=MemberId]') 
        .fadeIn(viewModel.fadeSpeed); 
      } 
     } 

      // when selected value is memberurl, may need to fade out id first 
     else if (unwrapped === 'MemberUrl') { 
      if ($('input[type=text][name=MemberId]:visible').length > 0) { 
       $('input[type=text][name=MemberId]:visible') 
        .fadeOut(viewModel.fadeSpeed, function() { 
         $('input[type=text][name=MemberUrl]') 
          .fadeIn(viewModel.fadeSpeed); 
       }); 
      } else { 
       $('input[type=text][name=MemberUrl]') 
        .fadeIn(viewModel.fadeSpeed); 
      } 
     } 
    } 
}; 

ko.applyBindings(viewModel); 

答えて

9

あなたはあなたの例を合わせて、この小さなを適応する必要がありますが、私はthis fiddleでテストすることを簡素化する必要がありました。ここで

が結合されています

var previousElement = null; 
ko.bindingHandlers.fadeSwitcher = { 
    init: function(element, valueAccessor) { 
     var value = valueAccessor(); 
     $(element).toggle(ko.utils.unwrapObservable(value)); 
    }, 
    update: function(element, valueAccessor) { 

     var value = ko.utils.unwrapObservable(valueAccessor()); 
     if (value) { 
      if (previousElement == null) { // initial fade 
       $(element).fadeIn(); 
      } else { 
       $(previousElement).fadeOut('fast', function() { 
        $(element).fadeIn(); 
       }); 
      } 
      previousElement = element; 
     }   
    } 
}; 
0

答えをあなたにTyrsiusをありがとうございます。私はフィドルからそれを適応させなければならなかった。私はそれが(foreachのなしで)問題のと同じラジオを動作させるために、わずかに修飾された結合を使用することができました:

@* radios same as in question *@ 
<div> 
    <input type="text" name="MemberId" placeholder="Enter Member ID" 
     data-bind="whoFader: who() === 'MemberId'" style="display: none" /> 
    <input type="text" name="MemberUrl" placeholder="Enter Member URL" 
     data-bind="whoFader: who() === 'MemberUrl'" 
     style="display: none; width: 450px;" /> 
</div> 

ko.bindingHandlers.whoFader = { 
    previousElement: null, 
    init: function (element, valueAccessor) { 
     var value = valueAccessor(); 
     $(element).toggle(ko.utils.unwrapObservable(value)); 
    }, 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     if (value) { 
      if (this.previousElement == null) { 
       $(element).fadeIn('fast'); 
      } else { 
       $(this.previousElement).hide(); 
       $(element).fadeIn('fast'); 
      } 
      this.previousElement = element; 
     } 
     else { 
      $(element).fadeOut('fast'); 
     } 
    } 
}; 
+0

私は助けてくれました。より多くのモデル指向のソリューションを検討したいかもしれません。あなたがMVVMのパターンに従えば、KOでもっと簡単になる傾向があります。 – Tyrsius

+0

@Tyrsius、 "モデル指向のソリューション"は、HTMLで明示的に出力する代わりに、foreachを使ってVMから無線をレンダリングすることを意味しますか? – danludwig

+1

はい、とりわけです。 MVVMパターンのアイデアは、ビューにデータが保持されておらず、モデルを表示する方法のみを知っているということです。すべてのデータはモデル内にある必要があります。これにより、ビューとモデルの両方をどのデータでも使用できます。 – Tyrsius

1

相手に少し遅れますが、多分それは誰かに使用でありますelse。

私はTyrsiusの答えを受け取り、それを自分のニーズに合わせて変更しました。このバージョンは観測可能なプロパティを扱い、変化するたびに古い値または新しい値をfadeOut/fadeInします。

Usage example: <span data-bind="fadeSwitcher: myObservable"></span> 

ko.bindingHandlers.fadeSwitcher = { 
    init: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     element.setAttribute('previousValue', value); 
     ko.bindingHandlers.text.update(element, ko.observable(value)); 
    }, 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     var previousValue = element.getAttribute('previousValue'); 
     if (value !== previousValue) { 
      $(element).fadeOut('fast', function() { 
       ko.bindingHandlers.text.update(element, ko.observable(value)); 
       $(element).fadeIn(); 
      }); 
      element.setAttribute('previousValue', value); 
     } 
    } 
};