从 Knockout.js 选项数组中删除后重新初始化 Materialize.css select 框
Re-init Materialize.css select box after removal from Knockout.js options array
我有一个 select 框,其中选项和 selection 通过 Knockout.js 处理。我想使用 Materialize CSS.
设置样式
这对于 select 框的初始显示以及当使用 'optionsAfterRender' 绑定到 (在添加每个选项后重新)初始化(浪费,但有效)。
删除选项时,Knockout.js 不提供类似于 'optionsAfterRender' 的任何内容,因此没有明显的方法来触发 Materialize CSS 魔法的重新初始化。
问题:有没有你能看到的非疯狂选项?
代码:
<select data-bind="
options: options,
optionsText: function(item) { return optionsText[item] },
value: displayedValue,
optionsAfterRender: function (option, item) {
setTimeout(function() {
$(option.parentElement).material_select();
}, 0);
}
">
</select>
('setTimeout' 是必需的,否则不会选择 selected 选项。)
A custom binding handler 更适合将自定义 UI 组件(如 material_select
)与 KnockoutJS 集成。下面是构建此类处理程序的一种方法:
ko.bindingHandlers["materializeSelect"] = {
after: ['options'],
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Initial initialization:
$(element).material_select();
// Find the "options" sub-binding:
var boundValue = valueAccessor();
// Register a callback for when "options" changes:
boundValue.options.subscribe(function() {
$(element).material_select();
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
}
};
function RootViewModel() {
var self = this, i = 2;
self.options = ko.observableArray([{id: 1, txt: "Option A"}, {id: 2, txt: "Option two"}]);
self.selectedOption = ko.observable(null);
// For testing purposes:
self.addOption = function() { self.options.push({id: ++i, txt: "Dynamic option " + i}); };
}
ko.applyBindings(new RootViewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.4/js/materialize.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.4/css/materialize.min.css" rel="stylesheet"/>
<select data-bind="materializeSelect: { options: options },
options: options,
optionsText: 'txt',
value: selectedOption">
</select>
<button data-bind="click: addOption">Add option dynamically</button>
老实说,我觉得这是一个 issue/omission 或者甚至是 MaterializeCSS 中的一个错误,它显然没有注意到 select
选项的变化。 IIRC 库,如 Select2 和 Chosen do 具有此功能。
无论如何,如果 MaterializeCSS 会 正确地注意到动态添加的选项,我仍然建议使用自定义绑定处理程序,只是一个更简单的处理程序:
ko.bindingHandlers["materializeSelect"] = {
after: ['options'],
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$(element).material_select();
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Handle ViewModel changes of which MaterializeCSS needs custom
// notification here.
}
};
Jeroen 的回答很好而且正确,我想添加一个使用 SO 注释的附录,但我认为使用完整格式更好看。
Materialize 在 select 上响应 disable
绑定似乎有点奇怪,特别是如果该禁用依赖于另一个可观察到的淘汰赛的更新(通常是这样) .
我在我的更新函数中使用了以下内容:
if(allBindings().disable != undefined && allBindings().disable == true){
$(element).prop("disabled", true);
}
else{
$(element).prop("disabled", false);
}
$(element).material_select();
我最初只是尝试在更新函数中调用 $(element).material_select()
,但它似乎有点无用,只能在某些时候工作。显式更改元素上的禁用 属性 似乎每次都有效。
可能有更简洁的方法来执行此操作,但希望此示例能够说明这一点:根据绑定状态显式设置禁用 属性。
我不知道使用其他绑定时是否会遇到类似的问题,visible
等,但如果是,这些问题可能会以类似的方式解决。
我有一个 select 框,其中选项和 selection 通过 Knockout.js 处理。我想使用 Materialize CSS.
设置样式这对于 select 框的初始显示以及当使用 'optionsAfterRender' 绑定到 (在添加每个选项后重新)初始化(浪费,但有效)。
删除选项时,Knockout.js 不提供类似于 'optionsAfterRender' 的任何内容,因此没有明显的方法来触发 Materialize CSS 魔法的重新初始化。
问题:有没有你能看到的非疯狂选项?
代码:
<select data-bind="
options: options,
optionsText: function(item) { return optionsText[item] },
value: displayedValue,
optionsAfterRender: function (option, item) {
setTimeout(function() {
$(option.parentElement).material_select();
}, 0);
}
">
</select>
('setTimeout' 是必需的,否则不会选择 selected 选项。)
A custom binding handler 更适合将自定义 UI 组件(如 material_select
)与 KnockoutJS 集成。下面是构建此类处理程序的一种方法:
ko.bindingHandlers["materializeSelect"] = {
after: ['options'],
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Initial initialization:
$(element).material_select();
// Find the "options" sub-binding:
var boundValue = valueAccessor();
// Register a callback for when "options" changes:
boundValue.options.subscribe(function() {
$(element).material_select();
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
}
};
function RootViewModel() {
var self = this, i = 2;
self.options = ko.observableArray([{id: 1, txt: "Option A"}, {id: 2, txt: "Option two"}]);
self.selectedOption = ko.observable(null);
// For testing purposes:
self.addOption = function() { self.options.push({id: ++i, txt: "Dynamic option " + i}); };
}
ko.applyBindings(new RootViewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.4/js/materialize.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.4/css/materialize.min.css" rel="stylesheet"/>
<select data-bind="materializeSelect: { options: options },
options: options,
optionsText: 'txt',
value: selectedOption">
</select>
<button data-bind="click: addOption">Add option dynamically</button>
老实说,我觉得这是一个 issue/omission 或者甚至是 MaterializeCSS 中的一个错误,它显然没有注意到 select
选项的变化。 IIRC 库,如 Select2 和 Chosen do 具有此功能。
无论如何,如果 MaterializeCSS 会 正确地注意到动态添加的选项,我仍然建议使用自定义绑定处理程序,只是一个更简单的处理程序:
ko.bindingHandlers["materializeSelect"] = {
after: ['options'],
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$(element).material_select();
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Handle ViewModel changes of which MaterializeCSS needs custom
// notification here.
}
};
Jeroen 的回答很好而且正确,我想添加一个使用 SO 注释的附录,但我认为使用完整格式更好看。
Materialize 在 select 上响应 disable
绑定似乎有点奇怪,特别是如果该禁用依赖于另一个可观察到的淘汰赛的更新(通常是这样) .
我在我的更新函数中使用了以下内容:
if(allBindings().disable != undefined && allBindings().disable == true){
$(element).prop("disabled", true);
}
else{
$(element).prop("disabled", false);
}
$(element).material_select();
我最初只是尝试在更新函数中调用 $(element).material_select()
,但它似乎有点无用,只能在某些时候工作。显式更改元素上的禁用 属性 似乎每次都有效。
可能有更简洁的方法来执行此操作,但希望此示例能够说明这一点:根据绑定状态显式设置禁用 属性。
我不知道使用其他绑定时是否会遇到类似的问题,visible
等,但如果是,这些问题可能会以类似的方式解决。