Knockout JS - 将数据绑定到我的表

时间:2015-12-09 17:26:18

标签: javascript jquery knockout.js

嗨大家我在淘汰时学到了新知识。我设法通过jsfiddle http://jsfiddle.net/N2zNk/49/重新创建我想在我的网站上完成的内容。我复制了代码并将其放入我的网站,唯一的区别是我通过AJAX从服务器获取数据。

现在发生的事情是我的表设法使用我的编辑按钮在我的表中创建了一行,但是没有呈现我的任何文本绑定。我相信Ajax的一些东西正在给我带来问题,但无法弄清楚它是什么。

有人会有任何线索吗?

控制台错误消息:

Uncaught ReferenceError: Unable to process binding "text: function (){return Incident }"
Message: Incident is not defined

HTML code:

<table class="table table-bordered table-hover text-center" id="example2">
    <thead>
        <tr>
            <th width="30" class="text-center"><i class="fa fa-list-alt fa-4"></i></th>
            <th width="75" class="text-center"> Incident <i class="fa fa-ticket"></i> </th>
            <th width="65" class="text-center"> Priorité <i class="fa fa-balance-scale"></i> </th>
            <th width="70" class="text-center"> Composante <i class="fa fa-building-o"></i> </th>
            <th width="300" class="text-center"> Description <i class="fa fa-ellipsis-h"></i> </th>
            <th width="100" class="text-center"> Date de début <i class="fa fa-calendar"></i> </th>
            <th width="100" class="text-center"> Responsable <i class="fa fa-user"></i> </th>
        </tr>
    </thead>
    <tbody data-bind="template: { name: 'Incidents', foreach: dataFromServer() }" />
    </tbody>
</table>

我的模板代码:

<script type="text/html" id="Incidents">
<tr>
    <td class='over_flow_control'><button class='edit_button btn btn-default btn-sm' type='button' value='Edit' data-bind="click: $parent.editProduct"><i class='glyphicon glyphicon-edit'></i></button></td>
    <td class='over_flow_control' data-bind="text: Incident"></td>
    <td class='over_flow_control'><h4><span class='priorité_span' data-bind="text:PrioritéValue"></span></h4></td>
    <td class='over_flow_control' data-bind="text:Composante"></td>
    <td class='over_flow_control text-left' data-bind="text:Description"></td>
    <td class='over_flow_control Date_de_début_cell' data-bind="text:Date_de_début"></td>
    <td class='over_flow_control' data-bind="text:ResponsableValue"></td>    
</tr>
</script>

我的javascript代码:

<script type="text/javascript">
function load_incidents(ID, Description, Composante, Incident, ÉtatValue, PrioritéValue, Duré, Date_de_début, Date_de_fin, Groupe_Support_Prime, Autres_Groupe_Support_Prime, ResponsableValue, Impact, Temps_Consacré, Type_de_tempsValue, Journal_des_actions, Dépanage, Suivi, Ressources) {
    var self = this;
    this.ID = ID;
    this.Description = ko.observable(Description);
    this.Composante = ko.observable(Composante);
    this.Incident = ko.observable(Incident);
    this.ÉtatValue = ko.observable(ÉtatValue);
    this.PrioritéValue = ko.observable(PrioritéValue);
    this.Duré = ko.observable(Duré);
    this.Date_de_début = ko.observable(Date_de_début);
    this.Date_de_fin = ko.observable(Date_de_fin);
    this.Groupe_Support_Prime = ko.observable(Groupe_Support_Prime);
    this.Autres_Groupe_Support_Prime = ko.observable(Autres_Groupe_Support_Prime);
    this.ResponsableValue = ko.observable(ResponsableValue);
    this.Impact = ko.observable(Impact);
    this.Temps_Consacré = ko.observable(Temps_Consacré);
    this.Type_de_tempsValue = ko.observable(Type_de_tempsValue);
    this.Journal_des_actions = ko.observable(Journal_des_actions);
    this.Dépanage = ko.observable(Dépanage);
    this.Journal_des_actions = ko.observable(Journal_des_actions);
    this.Suivi = ko.observable(Suivi);
    this.Ressources = ko.observable(Ressources);

    //This is the start edit group//
    this.editDescription = ko.observable(Description);
    this.editComposante = ko.observable(Composante);
    this.editIncident = ko.observable(Incident);
    this.editÉtatValue = ko.observable(ÉtatValue);
    this.editPrioritéValue = ko.observable(PrioritéValue);
    this.editDuré = ko.observable(Duré);
    this.editDate_de_début = ko.observable(Date_de_début);
    this.editDate_de_fin = ko.observable(Date_de_fin);
    this.editGroupe_Support_Prime = ko.observable(Groupe_Support_Prime);
    this.editAutres_Groupe_Support_Prime = ko.observable(Autres_Groupe_Support_Prime);
    this.editResponsableValue = ko.observable(ResponsableValue);
    this.editImpact = ko.observable(Impact);
    this.editTemps_Consacré = ko.observable(Temps_Consacré);
    this.editType_de_tempsValue = ko.observable(Type_de_tempsValue);
    this.editJournal_des_actions = ko.observable(Journal_des_actions);
    this.editDépanage = ko.observable(Dépanage);
    this.editJournal_des_actions = ko.observable(Journal_des_actions);
    this.editSuivi = ko.observable(Suivi);
    this.editRessources = ko.observable(Ressources);

    //end of the edit group//
    this.accept = function () {
    this.Description(this.editDescription());
    this.Composante(this.editComposante());
    this.Incident(this.editIncident());
    this.ÉtatValue(this.editÉtatValue());
    this.PrioritéValue(this.editPrioritéValue());
    this.Duré(this.editDuré());
    this.Date_de_début(this.editDate_de_début());
    this.Date_de_fin(this.editDate_de_fin());
    this.Groupe_Support_Prime(this.editGroupe_Support_Prime);
    this.Autres_Groupe_Support_Prime(this.editAutres_Groupe_Support_Prime());
    this.ResponsableValue(this.editResponsableValue());
    this.Impact(this.editImpact());
    this.Temps_Consacré(this.editTemps_Consacré());
    this.Type_de_tempsValue(this.editType_de_tempsValue());
    this.Journal_des_actions(this.editJournal_des_actions());
    this.Dépanage(this.editDépanage());
    this.Journal_des_actions(this.editJournal_des_actions());
    this.Suivi(this.editSuivi());
    this.Ressources(this.editRessources());
    return true;
    }.bind(this);

    //reset to originals on cancel
    this.cancel = function () {
    this.editDescription(this.Description());
    this.editComposante(this.Composante());
    this.editIncident(this.Incident());
    this.editÉtatValue(this.ÉtatValue());
    this.editPrioritéValue(this.PrioritéValue());
    this.editDuré(this.Duré());
    this.editDate_de_début(this.Date_de_début());
    this.editDate_de_fin(this.Date_de_fin());
    this.editGroupe_Support_Prime(this.Groupe_Support_Prime);
    this.editAutres_Groupe_Support_Prime(this.Autres_Groupe_Support_Prime());
    this.editResponsableValue(this.ResponsableValue());
    this.editImpact(this.Impact());
    this.editTemps_Consacré(this.Temps_Consacré());
    this.editType_de_tempsValue(this.Type_de_tempsValue());
    this.editJournal_des_actions(this.Journal_des_actions());
    this.editDépanage(this.Dépanage());
    this.editJournal_des_actions(this.Journal_des_actions());
    this.editSuivi(this.Suivi());
    this.editRessources(this.Ressources());
    }.bind(this);
}

Incidents = {
pvm: {},
productStore: {
    products: [],
    init: function (data) {
        this.products = $.map(data, function (product) {
            return new load_incidents(product.ID, product.Description(), product.Composante());
        });
        console.log(this.products);
    }
},  

init: function () {

var self = this;
dataFromServer = ko.observableArray([]);
$.getJSON("../../../../_vti_bin/listData.svc/GDI_PROD_Incidents?$filter=ÉtatValue%20ne%20%27Fermé%27&$orderby=PrioritéValue desc",
function (data) {
if (data.d.results) {
dataFromServer(JSON.stringify(data.d.results));
console.log(dataFromServer());
}
}
);
Incidents.productStore.init(dataFromServer());
},
productViewModel: function (data) {
        var self = this;
        var productsArray = [];

            productsArray = data;

        this.products = ko.observableArray(productsArray);
        this.selectedProduct = ko.observable();
        this.editProduct = function (productToEdit) {
            self.selectedProduct(productToEdit);

            // Incidents.pvm.selectedProduct(productToEdit);
        };
        this.acceptEdit = function () {
            var selected = Incidents.pvm.selectedProduct();
            if (selected.accept()) {
                Incidents.pvm.selectedProduct("");
                $('#dialogEditProduct').popup('close');
            }
        };
        this.cancelEdit = function () {
            Incidents.pvm.selectedProduct().cancel();
            Incidents.pvm.selectedProduct("");
            $('#dialogEditProduct').popup('close');
        };
    }
};
ko.bindingHandlers.jqButton = {
    init: function (element) {
        $(element).button();
    },
    update: function (element, valueAccessor) {
        var currentValue = valueAccessor();
        $(element).button("option", "disabled", currentValue.enable === false);
    }
};

ko.bindingHandlers.openProductDialog = {
    update: function (element, valueAccessor) {  
        var value = ko.utils.unwrapObservable(valueAccessor());
        if (value) {
            $.mobile.changePage("#dialogEditProduct", {
                role: 'dialog'
            });
            $("#dialogEditProduct").open();    
            // $("#dialogEditProduct").trigger('create');    
        }

    }
};

$.extend({
    isNumber: function (obj) {
        return !isNaN(parseFloat(obj)) && isFinite(obj);
    }
});

Incidents.init(); 
ko.applyBindings(Incidents);
</script>

2 个答案:

答案 0 :(得分:2)

看起来大多数问题是您没有正确使用var self=this模式。

通常的JavaScript构造函数如下所示:

var MyVm = function() {
  this.name = ko.observable('John');
  this.age = ko.observable(23);
}

然后你这样称呼它:

var myVm = new MyVm();

当你开始添加函数时,这种模式会变得复杂,因为你必须小心它的绑定方式。

var MyVm = function() {
  this.name = ko.observable('John');
  this.age = ko.observable(23);
  this.incAge = function() {
    this.age(this.age()+1);
  };
}

根据您的操作方式,当您致电incAge时,它可能无法正常工作,因为this可能与您的视图模型有所不同。这就是var self = this;模式存在的原因。但它的使用方式如下:

var MyVm = function() {
  var self = this;
  self.name = ko.observable('John');
  self.age = ko.observable(23);
  self.incAge = function() {
    self.age(self.age()+1);
  };
  return self;
}

使用此模式,您不必担心如何调用incAge

您粘贴了太多代码,因此很难看到确切的问题。 您应该仔细阅读:How to create a Minimal, Complete, and Verifiable example,这也可以帮助您解决自己的问题。即使这样,我也可以看到你没有正确使用这种模式。开始使用它,如我的例子所示,不要忘记必不可少的return self;。在你的情况下,你正在使用带参数的构造函数,如下所示:

var MyVm = function(_name, _age) {
  var self = this;
  self.name = ko.observable(_name);
  self.age = ko.observable(_age);
  self.incAge = function() {
    self.age(self.age()+1);
  };
  return self;
}

为了完成我的回答,我可以看到你将大多数属性直接映射到具有相同名称的observable。使用knockout mapping可以节省大量时间和代码。

答案 1 :(得分:1)

作为此模式的一个示例,我向您显示删除链接。它在你的小提琴中不起作用。

你必须先改变你的HTML:

    <a href="#" data-bind="click: $parent.removeItem">Delete</a>

然后将removeItem()函数添加到ViewModel:

productViewModel: function (data) {
    var self = this;
    var productsArray = [];
    if (data && data.length > 0) {
        productsArray = data;
    }
    self.products = ko.observableArray(productsArray);

    this.selectedProduct = ko.observable();

    this.removeItem = function (productToRemove){
        self.products.remove(productToRemove);
    }

如果您尝试执行此fiddle,则可以看到删除行。

如果您更改此行:

                self.products.remove(productToRemove);

这一个:

                this.products.remove(productToRemove);

(唯一的变化是 自我),它不起作用。

关于lists的Knockout教程对您非常有帮助。