์ ์ฒด ๊ฐ์ฒด๊ฐ ๋ฌธ์์ด์ด ์๋ ๊ฐ์ผ๋ก ๋ฐ์ธ๋ฉ๋๋ ๋ น์์ ์ ํ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
bootstrap-multiselect๋ ๋๋กญ๋ค์ด ๋ชฉ๋ก ํญ๋ชฉ์ ํด๋น ์ ํ ์ต์ ๊ณผ ๋ค์ ์ฐ๊ฒฐํ๊ธฐ ์ํด "๊ฐ"์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์ข์ํ์ง ์์์ต๋๋ค. ์ด๋ฅผ ์ํํ๋ ค๋ฉด ๋ น์์ ๋ฐ์ธ๋ฉ์ "optionsValue" ์์ฑ์ ์ค์ ํ์ฌ ์ต์ ์ "๊ฐ" ์์ฑ์ด ์๋๋ก ํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ "optionsValue" ์์ฑ์ ์ค์ ํ๋ฉด ์ ์ฒด ๊ฐ์ฒด๊ฐ ์๋ ๋ด selectedOptions observableArray์์ ํด๋น ๊ฐ๋ง ์ค์ ํ๋ ์์ ๊ฒฐ๊ณผ๊ฐ ๋ํ๋ฉ๋๋ค.
์ต์ ์ ์ ์ฒด ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉํ ์ ์๋ ๋ น์์ ๋ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ์ ์ผํ ์ฌ๋์ด ๋์ผ ๊ฐ๋ฅ์ฑ์ด ๋งค์ฐ ๋์ง๋ง ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ... ์ฌ๊ธฐ ํดํน ์์ ์ฌํญ์ด ์์ต๋๋ค.
"optionsKey" ๋ฐ "observableKey"๋ผ๋ ๋ ๊ฐ์ ์๋ก์ด ๋ถํธ์คํธ๋ฉ ๋ค์ค ์ ํ ์ต์ ์ ์์ฑํ์ฌ ๊ด๋ จ๋ ์ ์๋ ๊ฐ์ ์ด๋๋ก ๊ฐ์ผ ํ๋์ง ์ ์ ์์ต๋๋ค.
<select id="mySelect" data-bind="options: myOptions, selectedOptions: mySelectedOptions, optionsText: 'myDisplayText', optionsAfterRender: SetOptionKey, multiselect: { optionsKey: 'data-key', observableKey: 'Key' }" multiple="multiple"></select>
๋ด ๋ น์์ ๋ณด๊ธฐ ๋ชจ๋ธ์์ ๊ฐ ์ต์ ์ ๋ํด "optionsKey"๊ฐ ์ฐธ์กฐํ๋ ์์ฑ์ ์ค์ ํ์ต๋๋ค.
myVM.SetOptionKey = function ( option, item ) {
ko.applyBindingsToNode( option, { attr: { "data-key": item.Key } }, item );
};
์ด์ bootstrap-multiselect.js ํ์ผ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ฌ๊ธฐ์์ ๊ฐ์ฅ ๋จผ์ ํด์ผ ํ ์ผ์ ๋ น์์ ์ด๊ธฐํ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ถ๊ฐํ๋ ์๋จ์ ์๋ ๊ฒ์ ๋๋ค.
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
...
if (allBindings.has('selectedOptions')) {
var selectedOptions = allBindings.get('selectedOptions');
if (ko.isObservable(selectedOptions)) {
ko.computed({
read: function () {
selectedOptions();
// Added to handle knockout binding to an object...not just a value
// multiselect needs the selected property on the options, else it wont show them on refresh
if ((config.optionsKey !== undefined) &&
(config.optionsKey !== null) &&
(config.optionsKey.length > 0) &&
(config.observableKey !== undefined) &&
(config.observableKey !== null) &&
(config.observableKey.length > 0)) {
var _optionsKey = config.optionsKey;
var _observableKey = config.observableKey;
ko.utils.arrayForEach(selectedOptions(), function (selectedOption) {
$("option[" + _optionsKey + "='" + selectedOption[_observableKey]() + "']", $element).prop('selected', true);
})
}
setTimeout(function () {
$element.multiselect('refresh');
}, 1);
},
disposeWhenNodeIsRemoved: element
}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
}
}
...
๋ค์์ผ๋ก bootstrap-multiselect.js์ createOptionValue ํจ์๋ฅผ ์์ ํ์ฌ ๋จผ์ ์ด ํค๋ฅผ ๋ชฉ๋ก ํญ๋ชฉ์ ์ค์ ํ๋ ๊ฐ์ผ๋ก ์ฌ์ฉํ์ต๋๋ค.
createOptionValue: function (element) {
...
var value = $element.val();
// Added to handle knockout binding to an object...not just a value
if ((this.options.optionsKey !== undefined) && (this.options.optionsKey !== null) && (this.options.optionsKey.length > 0)) {
var key = $element.attr(this.options.optionsKey);
if ((key !== undefined) && (key !== null) && (key.length > 0)) {
value = key;
}
}
...
}
๋ง์ง๋ง์ผ๋ก ๊ฐ ๋์ ์ด ์์ฑ์ ๊ธฐ๋ฐ์ผ๋ก ์ต์ ์์๋ฅผ ์ฐพ๊ธฐ ์ํด bootstrap-multiselect.js์์ getOptionByValue ํจ์๋ฅผ ์์ ํด์ผ ํ์ต๋๋ค.
getOptionByValue: function (value) {
var valueToCompare = value.toString();
// Added to handle knockout binding to an object...not just a value
if ((this.options.optionsKey !== undefined) && (this.options.optionsKey !== null) && (this.options.optionsKey.length > 0)) {
var opt = $("option[" + this.options.optionsKey + "='" + valueToCompare + "']", this.$select).first();
if( (opt !== undefined) && (opt !== null) ) {
return $(opt);
}
}
var options = $('option', this.$select);
for (var i = 0; i < options.length; i = i + 1) {
var option = options[i];
if (option.value === valueToCompare) {
return $(option);
}
}
},
๊ฐ์ฌํฉ๋๋ค. FAQ์ ํฌํจํ๊ฒ ์ต๋๋ค! ๋๋ ์ด๊ฒ์ด ๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ๋ ๋์์ด ๋ ๊ฒ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค.
์ด ํ์ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๊ฐ์ฒด ์ ํ์ ๋ํ ๋ฐ์ธ๋ฉ๋ ์ํํ๋ ค๊ณ ํ์ผ๋ฉฐ ์ด ๊ธ์ด ๋งค์ฐ ๋์์ด ๋์์ต๋๋ค. @APM3 ์ ์ฝ๋ ์ธ์ ๋ด๊ฐ ํด์ผ ํ ์ ์ผํ ์ผ์ SetOptionKey ํจ์์์ ๋ด ์ต์ ์ "๊ฐ" ์์ฑ๋ ์ฑ์ฐ๋ ๊ฒ์ ๋๋ค.
self.SetOptionKey = function (option, item) {
ko.applyBindingsToNode(option, { attr: { "data-key": item.Value } }, item);
ko.applyBindingsToNode(option, { attr: { "value": item.Value } }, item);
}
์ด ๊ธ์ ์จ์ฃผ์ ์ ๋ค์ ํ ๋ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
์ง์ํ๋ ๊ฐ์ฒด์ ๋ น์์ ๋ฐ์ธ๋ฉ์ ์์ง ๋ฅผ ์ฐธ์กฐํ์ธ์. bootstrap-multiselect.js ํ์ผ์์ ์ค์ ๋ฐ์ธ๋ฉ์ ๊ต์ฒดํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์ด ์ฝ๋์์๋ ์ต์ ์ ์ค์ ํ๊ธฐ ์ํด VM์ ๋ฃ์ ํ์๊ฐ ์์ต๋๋ค.
//Just like this one
myVM.SetOptionKey = function ( option, item ) {
ko.applyBindingsToNode( option, { attr: { "data-key": item.Key } }, item );
};
์์์ ์ผ๋ก optionsAfterRender
์ถ๊ฐํ๊ธฐ ์ํด ๋ฐ์ธ๋ฉ์ ์ ์ฒ๋ฆฌ ๋ฅผ ์ถ๊ฐํ์ต๋๋ค.