Knockout学习之Collections

①数据集的绑定
在表的tbody上添加foreach即可实现对集合的迭代。ViewModel对象之间的相对关系类似于文件夹,可以嵌套,且存在“相对路径”.
例如在tbody上用foreach绑定person后,该table中可直接绑定person下的属性而不需要加前缀。
但是如果要绑定“根目录”下的属性则要添加前缀 $root.

<!DOCTYPE HTML>
<html>
<head>
    <title>对数据集合的绑定1</title>
    <script src="http://knockoutjs.com/js/jquery-1.4.2.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.1.0/knockout-min.js"></script>
</head>
<body>
    <table>
        <thead>
            <tr>
                <th>ABC</th>
                <th>小名</th>
                <th>年龄</th>
                <th>朋友信息</th>
            </tr>
        </thead>
        <tbody data-bind="foreach:persons">
            <tr>
                <td data-bind="text:$root.title"></td>
                <td data-bind="text:name""></td>
                <td data-bind="text:age"></td>
                <td data-bind="text:friends().name"></td>
            </tr>
        </tbody>
    </table>
    <hr />
    <p>Name:<input data-bind="value:PName" /></p>
    <button data-bind="click:addPerson">Add Person</button>
    
    <script type="text/javascript">
        function PersonViewModel(name,age) {
            this.name = ko.observable(name);
            this.age = ko.observable(age);
            this.friends = ko.observable({
                name: "John"
            });
        }
        
        function AppViewModel() {
            this.title = "-->";
            this.PName = ko.observable();
            this.persons = ko.observableArray([
                new PersonViewModel("Tiesto" ,15)
                , new PersonViewModel("Ray" ,16)
            ]);
            
            //方法绑定
            this.addPerson = function() {
                //向集合添加数据会反馈到View(利用对PName的绑定,获取要添加的名字)
                this.persons.push(new PersonViewModel(this.PName(),12));
            }
        }

        ko.applyBindings(new AppViewModel());
    </script>
</body>
</html>

②通过enable可以控制DOM元素是否可用
通过visible可以控制DOM元素是否可见
而其判断语句则如同普通的if,如
data-bind="enable:seats().length < 5"

<!DOCTYPE HTML>
<html>
<head>
    <title>对数据集合的绑定2</title>
    <script src="../JS/jquery-latest.min.js" type="text/javascript"></script>
    <script src="knockout-2.2.0.js" type="text/javascript"></script>
</head>
<body>
    <!--不仅可以绑定对象(集合),还可以绑定对象(集合)的属性-->
    <h2>Your seat reservations:<span data-bind="text:seats().length"></span></h2>
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Meal</th>
                <th>Surcharge</th>
                <th></th>
            </tr>
        </thead>
        <tbody data-bind="foreach:seats">
            <tr>
                <td><input data-bind="value:name" /></td>
                <td>
                    <!--下拉菜单的数据绑定
                    options必须是对象数组
                    optionsText则是options对象中的一个属性 注意要加引号
                    value则是指明select的影响范围
                    -->
                    <select data-bind="
                        options:$root.availableMeals
                        ,optionsText:'mealName'
                        ,value:meal
                    "></select>
                </td>
                <td data-bind="text:formattedPrice"></td>
                <td>
                    <!--如果在已经绑定了对象集合的元素中,给某个后代元素绑定事件的话,会默认传入当前对象-->
                    <a href="#" data-bind="click:$root.removeSeat">Remove</a>
                </td>
            </tr>
        </tbody>
    </table>
    <hr />
    <span>Name:<input data-bind="value:Person" /></span>
    
    <!--通过enable可以控制DOM元素是否可用-->
    <button data-bind="click:addSeat,enable:seats().length < 5">Add Person</button>
    <hr />
    
    <!--通过visible可以控制DOM元素是否可见-->
    <h3 data-bind="visible:totalSurchange() > 0">
        Total totalSurchange:$<span data-bind="text:totalSurchange"></span>
    </h3>
    
    <script type="text/javascript">
        //Model
        function SeatReservation(name, initialMeal) {
            var self = this;
            self.name = name;
            self.meal = ko.observable(initialMeal);
            self.formattedPrice = ko.computed(function() {
                var price = self.meal().price;
                return price ? "$" + price.toFixed(2) : "Free";
            });
        }

        //ViewModel
        function ReservationsViewModel() {
            var self = this;
            self.Person = ko.observable();
            self.availableMeals = [
                { mealName: "肉夹馍", price: 2.5 }
                , { mealName: "菜煎饼", price: 5 }
                , { mealName: "煎饼果子", price: 3.5 }
                ,{ mealName: "紫菜汤", price: 0 }
            ];

            self.seats = ko.observableArray([
                new SeatReservation("Rose", self.availableMeals[0])
                , new SeatReservation("John", self.availableMeals[1])
            ]);

            //通过对对象集合的修改(添加,删除,更新),页面(View)也会随之更新
            self.addSeat = function() {
                self.seats.push(new SeatReservation(self.Person(), self.availableMeals[0]));
            }

            self.removeSeat = function(seat) {
                self.seats.remove(seat);
            }

            self.totalSurchange = ko.computed(function() {
                var total = 0;
                for (var i = 0, len = self.seats().length; i < len; i++)
                    total += self.seats()[i].meal().price;
                return total.toFixed(2);
            });
        }

        ko.applyBindings(new ReservationsViewModel());
    </script>
</body>
</html>

原文地址:https://www.cnblogs.com/TiestoRay/p/2816915.html