Re-init Materialize.css select a window after removing from the array of options Knockout.js

I have a select box where parameters and selections are handled through Knockout.js. I want to create a style using Materialize CSS.

This works fine for the initial display of the select box, and when the parameters are added to the parameter of the observed attribute Knockout.js' observableArray, using the binding of 'optionsAfterRender' to (re) initialization after adding each option (wasteful, but it works).

When deleting an option, Knockout.js does not provide anything similar to "optionsAfterRender", so there is no obvious way to trigger reinitialization of the Materialize CSS magic.

Question: Are there any crazy options you can see?

the code:

<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" is necessary because otherwise the selected option is not selected.)

+7
javascript materialize
source share
2 answers

A user binding handler is more suitable for integrating a user interface user component such as material_select with KnockoutJS. Here is one way to create such a handler:

 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> 

Honestly, I feel like this is a problem / omission or even a bug in MaterializeCSS that does not seem to notice the change to select . IIRC libraries such as Select2 and Chosen have this feature.

In any case, if MaterializeCSS correctly sees the dynamically added parameters, I will still stay using a special binding handler, only much simpler:

 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. } }; 
+8
source share

Jeroen's answer is great and right, I wanted to add an add using SO comments, but this is better seen with full formatting, I think.

Materialization seems a little strange if it is tied to the disable binding when placed on an element, especially if this function is disabled when updating an observable other knockout (which is usually there).

In my update function, I use the following:

 if(allBindings().disable != undefined && allBindings().disable == true){ $(element).prop("disabled", true); } else{ $(element).prop("disabled", false); } $(element).material_select(); 

At first I tried just calling $(element).material_select() in the update function, but it seems to be a little low-powered, only working for a while. Explicitly changing the disabled property on an element seems to work every time.

Most likely, this is a much more concise way to do this, but hopefully this example illustrates the point: explicitly set the disabled property based on the binding state.

I do not know if similar problems occur using other bindings, visible , etc., but if they are, these problems can be solved in a similar way.

0
source share

All Articles