我有一个包含两个属性firstName
和lastName
的对象数组。在按钮上单击我想将下拉列表绑定到页面。目前我有:
$(document).ready(function ()
{
var obj1 =
{
firstName: "john",
lastName: "smith"
};
var obj2 =
{
firstName: "jane",
lastName: "doe"
}
var objArray = [];
objArray.push(obj1);
objArray.push(obj2);
$('#btnSubmit').click(function ()
{
makeDropDown(objArray);
});
function makeDropDown(array)
{
var $sel = $('<select/>');
for (var i = 0; i < array.length; i++)
{
for (var prop in array[i])
{
if(prop=='firstName')
var $option = $('<option/>').val(array[i][prop]).html(array[i][prop]).appendTo($sel);
}
}
$sel.appendTo('body');
}
});
这样可行,但我忍不住有更好的方法。我想我可以让函数在if语句中使用另一个参数(其中firstName),但这对我来说也不合适。这样做的好方法是什么?
答案 0 :(得分:3)
你可以创建一个简单的插件。
$.fn.createDropDown = function(options){ //Take options
var textField = options.textField, //get textfieldName from options
valueField = options.valueField || textField; //if no valueField specified default to text field
this.each(function(){
$('<select/>').append($.map(options.source, function (ob) { //iterate through the source
if(!ob[textField]) return true; //skip if atleast text field is not availabe in the object
return $('<option/>', { //create option and return
value: ob[valueField],
text: ob[textField]
});
})).appendTo(this); //append to each of the element in the selector
});
return this; //return it for chaining
}
并将其用作
var obj1 = {
firstName: "john",
lastName: "smith"
};
var obj2 = {
firstName: "jane",
lastName: "doe"
}
var objArray = [];
objArray.push(obj1);
objArray.push(obj2);
var options = { //set up options
source:objArray,
textField:'firstName',
valueField:'firstName'
}
$('#btnSubmit').click(function () {
$('body').createDropDown(options); //Just invoke it with options
});
<强> Demo 强>
答案 1 :(得分:2)
采用面向对象的方法既可以减少代码量,又可以减少错误。让我们首先在对象中添加自定义序列化方法,以表达它们应该如何呈现为<option>
。这样我们就不必在我们呈现它们的每个循环中编写代码,而是对象本身可以告诉代码的其余部分如何使它们出现在选择框中。
这是我们的第一遍。我们将从一个简单的方法开始,通过在每个对象中内联我们的序列化方法来证明在这里更加面向对象的另一个好处。
var obj1 =
{
firstName: "john",
lastName: "smith",
toOption: function () {
return $('<option/>').val(this.firstName).html(this.firstName);
}
};
var obj2 =
{
firstName: "jane",
lastName: "doe"
toOption: function () {
return $('<option/>').val(this.firstName).html(this.firstName);
}
};
var objArray = [];
objArray.push(obj1);
objArray.push(obj2);
$('#btnSubmit').click(function ()
{
makeDropDown(objArray);
});
function makeDropDown(array)
{
var $sel = $('<select/>');
for (var i = 0; i < array.length; i++)
{
array[i].toOption().appendTo($sel);
}
$sel.appendTo('body');
}
现在我们的for循环更易于阅读,我们可以在其他地方轻松创建这些<option>
代码,而无需复制和粘贴该代码。
然而,这仍然不是最理想的,因为我们在每个对象中都写了toOption
函数。由于我们发现自己在对象中创建方法,而不是重复地内联它,让我们自己创建这种类型的通用对象。我称之为Person
。作为一个额外的好处,我们现在可以直接创建内联,而不是编写详细的JavaScript对象。
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.toOption = function () {
return $('<option/>').val(this.firstName).html(this.firstName);
};
}
var objArray = [];
objArray.push(new Person('john', 'smith'));
objArray.push(new Person('jessica', 'jones'));
$('#btnSubmit').click(function () {
makeDropDown(objArray);
});
function makeDropDown(array) {
var $sel = $('<select/>');
for (var i = 0; i < array.length; i++) {
array[i].toOption().appendTo($sel);
}
$sel.appendTo('body');
}
这也意味着我们可以在一个地方改变我们的人物渲染方式,而不是改变我们的代码库。
答案 2 :(得分:2)
这与OO无关,但具有代码可重用性。是的,属性名的参数很好。您也可以返回select元素,而不是将其附加到正文,以提供更大的灵活性。
$(document).ready(function() {
var objArr = [
{
firstName: "john",
lastName: "smith"
},
{
firstName: "jane",
lastName: "doe"
}
];
$('#btnSubmit').click(function() {
makeDropDown(objArray, "firstName").appendTo('body');
});
function makeDropDown(array, prop) {
var $sel = $('<select/>');
for (var i = 0; i < array.length; i++)
$sel.append($('<option/>').val(array[i][prop]).text(array[i][prop]));
return $sel;
}
});