0

我有一个具有两个属性的对象数组,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),但这对我来说也不合适。这样做的好的OO方式是什么?

4

3 回答 3

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
    });

演示

于 2013-10-08T01:10:32.887 回答
2

采用面向对象的方法既可以减少代码量,也可以减少出错的可能性。让我们首先在您的对象中添加一个自定义序列化方法,以表达它们应该如何呈现为<option>s。这样,我们不必在渲染它们的每个循环中编写该代码,而是对象本身可以告诉其余代码如何使它们出现在选择框中。

这是我们的第一关。我们将从一个简单的方法开始,通过将我们的序列化方法内联在每个对象中来展示这里更加面向对象的另一个好处。

   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');
 }

这也意味着我们可以在一个地方改变我们的 Persons 渲染方式,而不是在我们的代码库中。

于 2013-10-08T01:04:46.800 回答
2

这与 OO 无关,但与代码可重用性有关。是的,propertyname 的参数很好。您还可以返回选择元素而不是将其附加到正文中,以提供更大的灵活性。

$(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;
    }
});
于 2013-10-08T01:07:50.773 回答