5

3 つのラジオ ボタンのセットがあるとします。

<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>

ユーザーが最初のラジオ ボタン (Mine/Myself) を選択した場合、追加の入力は必要ありません。ただし、2 番目または 3 番目を選択する場合は、追加の入力必要です。

<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]'"依存するテキスト ボックスをオンにするだけで十分簡単です。しかし、フェード イン/アウト トランジションを追加したい場合はどうすればよいでしょうか?

ノックアウト サイトのサンプル カスタムを試してみたところ、そのfadeVisible bindingHandler仕組みが理解できました。ただし、これはテキスト ボックスのフェードアウトとフェードインを同時に行います。ラジオ'MemberId'が選択されていて、ユーザーが'MemberUrl'ラジオを選択した場合、MemberIdテキスト ボックスがフェードインするMemberUrlテキスト ボックスがフェードアウトするようにします。

以下は私が今持っているもので、動作しますが、最適ではないと思います。前の要素がフェードアウトするまでフェードインを実行しないようにするには、他にどのようにノックアウトに指示できますか? 別の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);
4

3 に答える 3

9

あなたはあなたの例に合うようにこれを少し適応させる必要があるでしょう、しかし私はこのフィドルでテストするためにそれを単純化する必要がありました。

バインディングは次のとおりです。

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;
        }        
    }
};
于 2012-07-11T16:53:11.493 に答える
0

答えてくれてありがとうティリシウス。私はそれをフィドルから適応させる必要がありました。少し変更したバインディングを使用して、質問と同じラジオで動作させることができました(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');
        }
    }
};
于 2012-07-11T18:28:11.250 に答える