Say I have a set of 3 radio buttons:
假设我有一套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>
When the user selects the first radio button (Mine/Myself), no additional input is required. However, when selecting the second or third, additional input is required:
当用户选择第一个单选按钮(我/我)时,不需要额外的输入。但是,在选择第二个或第三个输入时,需要增加输入:
<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>
It is easy enough to just have data-bind="visible: who() === '[MemberId|MemberUrl]'"
on the dependent text boxes. However, what if I want to add fade in/out transitions?
只需在依赖文本框中使用data-bind="visible: who() == '[MemberId|MemberUrl]'"即可。但是,如果我想要添加渐变/渐变过渡呢?
I tried out the example custom fadeVisible
bindingHandler
from the knockout site, and I understand how it works. However this will fade out and fade in the text boxes at the same time. If radio 'MemberId'
is selected, and user selects 'MemberUrl'
radio, I want the MemberId
text box to fade out before the MemberUrl
text box fades in.
我在knockout网站上试用了自定义fadeVisible bindingHandler的示例,我理解它是如何工作的。然而,这将在文本框中同时淡出和淡出。如果选择了radio 'MemberId',用户选择'MemberUrl' radio,我希望在MemberUrl文本框淡出之前,MemberId文本框淡出。
Below is what I have now, and it works, but I don't think it's optimal. How else can knockout be told to not perform the fade in until a previous element has been faded out? Do I need another ko.observale
, or possibly a ko.computed
?
下面是我现在所拥有的,它是有效的,但我不认为它是最优的。还可以告诉knockout在之前的元素消失之前不要执行渐变吗?我需要另一个ko吗?天文台,或者可能是计算机?
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);
3 个解决方案
#1
9
You will have to adapt this a little to fit your example, but I needed to simplify it to test in this fiddle.
您将不得不对它进行一些调整以适应您的示例,但是我需要简化它以在这个小提琴中进行测试。
Here is the binding:
这是绑定:
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;
}
}
};
#2
1
A bit late to the party, but maybe it is of use to someone else.
聚会有点晚了,但可能对别人有用。
I've taken Tyrsius' answer and changed it to fix my own needs; this version deals with an observable property and will fadeOut/fadeIn the old/new value whenever it changes.
我接受了泰修斯的回答,改变了答案以满足我自己的需要;这个版本处理的是一个可观察的属性,当它发生变化时,它会以旧值/新值的形式出现。
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);
}
}
};
#3
0
Thank you Tyrsius for the answer. I did have to adapt it from the fiddle. I was able to use a slightly modified binding to get it to work with the same radios as in the question (without a foreach):
谢谢泰劳修斯的回答。我确实需要把它从小提琴上调整过来。我可以使用一个稍微修改过的绑定使它与问题中的相同无线电(没有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');
}
}
};
#1
9
You will have to adapt this a little to fit your example, but I needed to simplify it to test in this fiddle.
您将不得不对它进行一些调整以适应您的示例,但是我需要简化它以在这个小提琴中进行测试。
Here is the binding:
这是绑定:
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;
}
}
};
#2
1
A bit late to the party, but maybe it is of use to someone else.
聚会有点晚了,但可能对别人有用。
I've taken Tyrsius' answer and changed it to fix my own needs; this version deals with an observable property and will fadeOut/fadeIn the old/new value whenever it changes.
我接受了泰修斯的回答,改变了答案以满足我自己的需要;这个版本处理的是一个可观察的属性,当它发生变化时,它会以旧值/新值的形式出现。
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);
}
}
};
#3
0
Thank you Tyrsius for the answer. I did have to adapt it from the fiddle. I was able to use a slightly modified binding to get it to work with the same radios as in the question (without a foreach):
谢谢泰劳修斯的回答。我确实需要把它从小提琴上调整过来。我可以使用一个稍微修改过的绑定使它与问题中的相同无线电(没有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');
}
}
};