Say mam zestaw 3 przyciski radia:KnockoutJS: Obraz pojawia się po zanikaniem coś innego
<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>
Gdy użytkownik wybierze pierwszą opcję (kopalnia/ja), nie jest wymagane dodatkowe wejście. Jednak przy wyborze drugiego lub trzeciego, dodatkowego wejścia jest wymagane:
<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>
Łatwo jest po prostu mieć data-bind="visible: who() === '[MemberId|MemberUrl]'"
na utrzymaniu polach tekstowych. Co jednak, jeśli chcę dodać przejścia między wejściami i wyjściami?
Wypróbowałem przykład niestandardowy fadeVisible
bindingHandler
z witryny nokautowej i rozumiem, jak to działa. To jednak zniknie i znikną w polach tekstowych w tym samym czasie. Jeśli radiowy 'MemberId'
jest zaznaczone, a użytkownik wybiera 'MemberUrl'
radia, chcę okno MemberId
tekst do zanikania przed pole MemberUrl
tekst zanika w.
Poniżej jest to, co mam teraz, i to działa, ale don” Uważam, że jest optymalna. Jak inaczej może zostać nokautowany, aby nie przeprowadzać zanikania, dopóki poprzedni element nie zniknie? Czy potrzebuję kolejnego ko.observale
lub ewentualnie 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);
Cieszę się, że mogę pomóc. Możesz rozważyć bardziej zorientowane na model rozwiązanie. Sprawy będą prostsze z KO, jeśli zastosujesz wzór MVVM. – Tyrsius
@Tyrsius, przez "rozwiązanie zorientowane na model", czy używasz foreach do renderowania radia z vm, zamiast wyprowadzać je jawnie w HTML? – danludwig
Tak, między innymi. Idea wzorca MVVM polega na tym, że widok nie zawiera żadnych danych, a jedynie wie, jak wyświetlić model. Wszystkie dane powinny znajdować się w modelu. Dzięki temu zarówno widok, jak i model mogą być używane przez dowolne dane. – Tyrsius