无法处理绑定foreach与无法读取属性

时间:2015-03-02 13:58:37

标签: javascript knockout.js

在我向此演示代码添加删除功能之前,我的整个代码运行良好。 虽然我将这个绑定称为$root但是它给出了同样的错误。 我还附上了我得到的错误的屏幕截图。

 //my product class
          function Product(name, price) {

                this.name = ko.observable(name);
                this.price = ko.observable(price);

            };

    //my observable array
            this.shoppingCart = ko.observableArray([

                new Product("milk", 10.99),
                new Product("bread", 7.99),
                new Product("Jam",1.39)

            ]);       


    //below is my view model

            function personViewModel() {
                var self = this;

                firstName= ko.observable("John");
                lastName = ko.observable("Smith");
                checkOut = function () {
                    alert("Trying to Checkout");
                };

                fullName = ko.computed(function () {
                    return firstName() + " " + lastName();
                })

                this.addProduct = function () {

                    self.shoppingCart.push(new Product("Yogurt", 10.99));

                };

              //this method is bind with the button and producing error
                this.removeProduct = function (product) {
                    self.shoppingCart.remove(product)
                };

            };
            ko.applyBindings(personViewModel);

<!-- language: lang-html -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
    <body>
        <h1>Hello, Knockout.js</h1>
        <p><span data-bind='text: fullName'></span>'s Shopping cart</p>
        <button data-bind="click: checkOut">Checkout</button>
        <table>
            <thead>
                <tr>
                    <th>Product</th>
                    <th>Price</th>
                </tr>
            </thead>
            <tbody data-bind="foreach: shoppingCart">
                <tr>
                    <td data-bind="text: name"></td>
                    <td data-bind="text:price"></td>

                  <!--below binding is breaking the script-->

                    <td><button data-bind="click: $root.removeProduct">Remove</button></td>
                </tr>
            </tbody>
        </table>
        <button data-bind="click: addProduct">Add Item</button>
    </body>

<!-- end snippet -->

1 个答案:

答案 0 :(得分:0)

这里的错误是由函数的范围和可观察数组引起的。

绑定无法找到相应的视图模型对象。

以下是两种解决方案。请查看这些JS小提琴。

jsfiddle.net/y7wrjywn,其中可观察数组在视图模型定义中。

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<body>
     <h1>Hello, Knockout.js</h1>

    <p><span data-bind='text: fullName'></span>'s Shopping cart</p>
    <button data-bind="click: checkOut">Checkout</button>
    <table>
        <thead>
            <tr>
                <th>Product</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: shoppingCart">
            <tr>
                <td data-bind="text: name"></td>
                <td data-bind="text:price"></td>
                <!--below binding is breaking the script-->
                <td>
                    <button data-bind="click: $root.removeProduct">Remove</button>
                </td>
            </tr>
        </tbody>
    </table>
    <button data-bind="click: addProduct">Add Item</button>
</body>

//the script

         function Product(name, price) {

             this.name = ko.observable(name);
             this.price = ko.observable(price);

         };

         function personViewModel() {
             var self = this;

             self.firstName = ko.observable("John");
             self.lastName = ko.observable("Smith");
             self.checkOut = function () {
                 alert("Trying to Checkout");
             };

             self.fullName = ko.computed(function () {
                 return self.firstName() + " " + self.lastName();
             })

             self.addProduct = function () {

                 self.shoppingCart.push(new Product("Yogurt", 10.99));

             };

             self.shoppingCart = ko.observableArray([

             new Product("milk", 10.99),
             new Product("bread", 7.99),
             new Product("Jam", 1.39)

             ]);


             //this method is bind with the button and producing error
             self.removeProduct = function (product) {
                 self.shoppingCart.remove(product)
             };

         };

         ko.applyBindings(new personViewModel);

http://jsfiddle.net/satyanshua/eawd9y06/1/,其中的函数取自viewmodel

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<body>
     <h1>Hello, Knockout.js</h1>

    <p><span data-bind='text: fullName'></span>'s Shopping cart</p>
    <button data-bind="click: checkOut">Checkout</button>
    <table>
        <thead>
            <tr>
                <th>Product</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: shoppingCart">
            <tr>
                <td data-bind="text: name"></td>
                <td data-bind="text:price"></td>
                <td>
                    <button data-bind="click: removeProduct">Remove</button>
                </td>
            </tr>
        </tbody>
    </table>
    <button data-bind="click: addProduct">Add Item</button>
</body>


function Product(name, price) {

    this.name = ko.observable(name);
    this.price = ko.observable(price);

}

shoppingCart = ko.observableArray([

new Product("milk", 10.99),
new Product("bread", 7.99),
new Product("Jam", 1.39)

]);

addProduct = function () {

    shoppingCart.push(new Product("Yogurt", 10.99));

};

self.removeProduct = function (product) {
    shoppingCart.remove(product);
};


function personViewModel() {
    var self = this;

    firstName = ko.observable("John");
    lastName = ko.observable("Smith");
    checkOut = function () {
        alert("Trying to Checkout");
    };

    fullName = ko.computed(function () {
        return firstName() + " " + lastName();
    });


}
ko.applyBindings(new personViewModel());