简体   繁体   English

使用Knockout Observable Array时UI不更新

[英]UI not updating while using Knockout Observable Array

I am new to knockout. 我是淘汰赛的新手。 I am trying to use observable arrays to track the changes from UI. 我正在尝试使用可观察的数组来跟踪UI的更改。 The UI is loading with the initial data which is stored in the array. UI正在加载存储在数组中的初始数据。 And i am trying to add new object into the array dynamically from another screen. 我正在尝试从另一个屏幕向数组动态添加新对象。

Now i am able to add new object into the array. 现在,我可以将新对象添加到数组中。 But UI is not getting reflected with new changes in the array. 但是,UI并未反映在数组中的新变化中。 Below is my html and javascript code. 以下是我的html和javascript代码。

Am i missing something. 我错过了什么吗?

<html>
<head>
    <link rel="stylesheet" href="bootstrap.css" type="text/css" />
    <link rel="stylesheet" href="bootstrap-theme.css " type="text/css" />
    <script src="jquery.js" type="text/javascript"></script>
    <link rel="stylesheet" href="prodconfig.css " type="text/css" />    
    <script src="jquery.mobile.min.js" type="text/javascript"></script>
    <link rel="stylesheet" href="cordys.min.css" type="text/css" />
    <link rel="stylesheet" href="jquery.mobile.structure.min.css" type="text/css" />
    <script src="knockout.js" type="text/javascript"></script>
    <script src="prodconfig.js" type="text/javascript"></script>
</head>
<body>
    <div data-role="page" id="productsPage" class="dataContainer">
        <div id="productDetails">
            <div data-role="content" id="productTable">
                <table data-role="table" class="ui-responsive table">
                    <thead>
                        <tr>
                          <th data-priority="6">Product Name</th>
                          <th data-priority="1">Description</th>
                          <th data-priority="2">Parent?</th>
                        </tr>
                    </thead>
                    <tbody id="pBody"  data-bind="foreach: products">
                        <tr class="success">
                          <td><span data-bind="text: name"></span></td>
                          <td><span data-bind="text: desc"></span></td>
                          <td></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div id="prodButtons">
            <button id="addProdProduct">Add Product</button>
            <button id="addProdChar">Add Characteristics</button>
            <button id="prodButton">Next</button>
        </div>
    </div>  
    <div id="addProductPage" data-role="page" >
        <span><h3>Product Name</h3></span><input type="text" id="prodNameId"></input>
        <span><h3>Product Desc</h3></span><input type="text" id="prodDescId"></input>
        <span><h3>Is Parent</h3></span><input type="text" id="prodIsParentId"></input>
        <button id="addProdButton">OK</button>
    <div>
</body>

var configArray = new Array();
var products = [];
var services = new Array();
var chars = [];
var prd;



for(var i=0;i<2;i++){
    var product = new Object();
    product["name"] = "prod"+i+"Name";
    product["desc"] = "prod"+i+"Desc";
    product["isParent"] = "prme";

    for(var j=0;j<2;j++){
            var charr = new Object();
            charr["name"] = "prod"+i+"char"+j;
            charr["val"] = "prod"+i+"char"+j+"val";
            chars[j] = charr;
    }
    product["chars"] = chars;
    products[i] = product;

}

var ProductViewModel =  function(items) {
    this.items = ko.observableArray(items);
    this.itemToAdd = ko.observable("");
    this.addItem = function() {
        if (this.itemToAdd() != "") {
            this.items.push(this.itemToAdd()); 
            this.itemToAdd(""); 
        }
    }.bind(this);  
};

$(function(){
    $('#addProdProduct').click(function() {
        window.location.href = "#addProductPage";
    });
    $('#addProdButton').click(function() {
        addProduct();
    });
    prd = new ProductViewModel(products);
    ko.applyBindings(prd);

});

function addProduct(){
    var product = new Object();
    product["name"] = $('#prodNameId').val();
    product["desc"] = $('#prodDescId').val();
    product["isParent"] = $('#prodIsParentId').val();
    prd.itemToAdd(product);
    prd.addItem();
    window.location.href = '#';
}

You are binding to the products variable instead of to the items field on your viewmodel. 您将绑定到products变量,而不是视图模型上的items字段。

Change your binding to: 将绑定更改为:

<tbody id="pBody"  data-bind="foreach: items">

The code below shown a sample procedure for inserting data using knockoutjs MVVM pattern. 下面的代码显示了使用基因敲除MVVM模式插入数据的示例过程。 Here i using bootstrap Modal Popup for inserting Data. 在这里,我使用Bootstrap Modal Popup插入数据。

HTML 的HTML

<div class="row">
<button type="button" class="btn btn-primary pull-right" data-bind="click:add" data-toggle="modal" data-target="#myModal1">
    <i class="fa fa-plus"></i> Add New Data
</button>
<table class="table">
    <thead>
        <tr>
            <th>Name</th>
            <th>Action</th>
        </tr>
    </thead>
    <tbody data-bind="template:{name:'item-view-template',foreach:products}"></tbody>
</table>
</div>
<script type="text/html" id="item-view-template">
<tr>
    <td class="text-left" data-bind="text:ProductName"></td>
    <br />
/tr>
</script>
<div class="modal fade" id="myModal1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Add Data</h4>
            </div>
            <div class="modal-body" data-bind="template:{name:'item-create-template',data:selectedData}">
                <div class="row">
                    <div class="col-md-12"></div>
                </div>
            </div>
        </div>
    </div>
</div>
  <script type="text/html" id="item-create-template">
   <form>
    <fieldset>
        <div class="form-group col-md-6">
            <label>Name</label>
            <input type="text" class="form-control" data-bind="value:ProductName" />
        </div>
        <button class="btn btn-primary" data-bind="click:$parent.save">Save</button>
        <button class="btn btn-default" data-dismiss="modal">Cancel</button>
    </fieldset>
   </form>
  </script>
  <script type="text/javascript">
    var vm = new ProductViewModel();
    ko.applyBindings(vm);
    vm.init();
  </script>

View Model Js File 查看模型Js文件

function ProductViewModel() {
var self = {};
self.data = ko.observableArray();
self.products = ko.observableArray();
self.selectedData = ko.observable(Product({}));

self.init = function () {
    $.get('/MyController/GetAll', function (data) {
        $.each(data, function (key, value) {
            self.products.push(Product(value));
        });
    });
};
self.add = function () {
    self.selectedData(Product({}));
};
self.save = function() {
    if (self.selectedData()) {
        var jsonData = ko.toJS(self.selectedData);
        $.post('/MyController/Create', jsonData, function(data) {
            if (data.Status == true) {
                $('#myModal1').modal('hide');
                bootbox.alert("Product created successfully", function() {
                    self.Products.removeAll();
                    $.get('/MyController/GetAll', function (result) {
                        $.each(result.Products, function (key, value) {
                            self.Products.push(Product(value));
                        });
                    });
                });
            } else {
                bootbox.alert("Duplicate values not allowed..!!");
            }
        });
    } else {
       bootbox.alert("Error!!");
    }
};
return self;
}

And the Model 和模型

function Product(product) {
var self = {};
self.Id = ko.observable(product.Id || '');
self.ProductName = ko.protectedObservable(product.Name || '');
return self;
}

I think this will help you 我想这对你有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM