我们一直在和和Chosen
一起使用库。一切工作正常,直到我们从切换到现在使用捆绑。问题是,当我们更改下拉列表中的值时,不会更新。RequireJs
KnockOut
RequireJS
commonjs
webpack
knockout observable
chosen
这是使用的javascript代码RequireJs
。
define(['knockout', 'text!./employee-setup.html', 'utils', 'panel-section', 'toastr', 'jquery', 'knockout-postbox', 'knockout-projections', 'chosen', 'jsteps'], function (ko, template, utils, PanelSection, toastr, $, _, _, _, jsteps) {
function EmployeeSetup(params) {
var self = this;
this.agentTypes = ko.observableArray();
this.agentType = ko.observable();
this.loadAgentTypes = function () {
$.ajax({
url: '/Employee/GetAgentTypes',
method: 'POST',
dataType: 'json',
success: function (result) {
if (utils.handleAjaxResult(result) && result.Data) {
self.agentTypes([]);
var agentType = [{ ID: "", Name: "" }];
$.each(result.Data, function (i, item) {
agentType.push({ID: item.ID, Name: item.Name});
});
self.agentTypes(agentType);
$('#agentType').chosen({ allow_single_deselect: true, width: '310px' });
$('#agentType').trigger("chosen:updated");
} else {
}
},
error: function () {
toastr.error('Could not load agent types');
}
});
};
self.loadAgentTypes();
};
return { template: template, viewModel: EmployeeSetup };
});
该组件的html:
<div class="input-container" data-bind="">
<select data-bind="value: agentType, options: agentTypes, optionsText: 'Name'" data-placeholder="Select Agent Type..." id="agentType" class="chosen-select sp-uin-dropdown" tabindex="2"> </select>
</div>
这是使用的代码 commonjs
var ko = require('knockout'),
utils = require('utils'),
PanelSection = require('panel-section'),
toastr = require('toastr'),
$ = require('jquery');
require('knockout-postbox');
function ViewModel(params) {
var self = this;
this.agentTypes = ko.observableArray();
this.agentType = ko.observable();
this.loadAgentTypes = function () {
$.ajax({
url: '/Employee/GetAgentTypes',
method: 'POST',
dataType: 'json',
success: function (result) {
if (utils.handleAjaxResult(result) && result.Data) {
self.agentTypes([]);
var agentType = [{ ID: "", Name: "" }];
$.each(result.Data, function (i, item) {
agentType.push({ID: item.ID, Name: item.Name});
});
self.agentTypes(agentType);
$('#agentType').chosen({ allow_single_deselect: true, width: '310px' });
$('#agentType').trigger("chosen:updated");
} else {
}
},
error: function () {
toastr.error('Could not load agent types');
}
});
};
self.loadAgentTypes();
}
module.exports = { viewModel: ViewModel, template: require('./template.html') };
它使用的是与html
上述相同的文件。
在中,webpack.config.js
我们定义了到jquery
和的路径chosen
。
它加载chosen dropdown
正确。但是,当我subscribe
观察到时,下拉列表更改时不会更新值。初始加载时,我只能从控制台看到一次该值。
self.agentType.subscribe(function (value) {
console.log('value', value);
}, this)
因此,很少有文章建议使用bindingHandlers
。我已经在应用程序中尝试了JSFiddle的工作代码,但仅从初始加载中获取了该值。
关于如何解决此问题或造成此问题的任何建议?
此问题是由引起的webpack
。为了解决这个问题,我的同事写了一个习惯bindingHandler
。
HTML
代码:
<div class="input-container">
<select data-bind="
value: agentType,
options: agentTypes,
optionsText: 'Name',
dropdown: {
width: '310px',
allow_single_deselect: true
} "
data-placeholder="Select Agent Type..." id="agentType">
</select>
自定义bindingHandler
:
// a dropdown handler, which currently utilizes the Chosen library
ko.bindingHandlers.dropdown = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext){
// get chosen element
var $element = $(element);
// get options (if any) to pass to chosen when creating
var options = ko.unwrap(valueAccessor());
// NOTE: when using Chosen w/ webpack, the knockout bindings no longer
// fired. This event handler is to remedy that. It watches the change
// event for the underlying <select> (which chosen updates), and
// updates the corresponding observables mapped to value and selectedOptions.
// Only one should be bound, value for single select, selectedOptions for multi-select
// binding direction: Knockout <- Chosen
$element.on('change', function(e, item) {
var valueProp = allBindings.has('value') && allBindings.get('value');
var selectedOptionsProp = allBindings.has('selectedOptions') && allBindings.get('selectedOptions');
if (item) {
if (allBindings.has('options')) {
var allOptions = ko.unwrap(allBindings.get('options'));
if (valueProp) {
// single select
if (ko.isObservable(valueProp)) {
if (!item.isMultiple) {
if (item.selecting) {
valueProp(allOptions[item.index]);
} else {
valueProp(null);
}
}
}
}
if (selectedOptionsProp) {
// multi select
if (ko.isObservable(selectedOptionsProp)) {
if (item.isMultiple) {
// handle multi select
if (item.selecting) {
// select
selectedOptionsProp.push(allOptions[item.index]);
} else {
// deselect
selectedOptionsProp.remove(allOptions[item.index]);
}
}
}
}
}
} else {
// this is triggered w/o args when the control is reset. This happens when deselecting during single-select
if (valueProp) {
// single select
if (item === undefined && ko.isObservable(valueProp)) {
valueProp(null);
}
}
}
});
// handle updating the chosen component's UI when the underlying
// options, selectedOptions or value changes
// binding direction: Knockout -> Chosen
['options', 'selectedOptions', 'value'].forEach(function(propName){
if (allBindings.has(propName)){
var prop = allBindings.get(propName);
if (ko.isObservable(prop)){
//console.log('subscribing to:', propName, ' for:', $element);
prop.subscribe(function(value){
if (value != null) {
//console.log('calling chosen:updated');
var options = ko.unwrap(allBindings.get('options'));
// console.log('got options:', options);
if (options) {
if (options.indexOf(value) > -1) {
// item is in options
// console.log('value is in options:', value);
} else {
// item is not in options, try to match ID
options.some(function (item) {
if (item.ID == value) {
// update the obs. to the entire item, not the ID
prop(item);
}
});
}
}
}
$element.trigger('chosen:updated');
});
}
}
});
// add chosen css class (not sure this is needed)
$element.addClass('chosen-select');
// create chosen element, passing in options if any were specified
if (typeof options === 'object') {
$element.chosen(options);
} else {
$element.chosen();
}
$element.trigger('chosen:updated');
}
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句