KnockoutJS - 可观察对象的可观察数组,包含来自 SQL 服务器的数据

Posted

技术标签:

【中文标题】KnockoutJS - 可观察对象的可观察数组,包含来自 SQL 服务器的数据【英文标题】:KnockoutJS - Observable Array of Observable objects with Data from SQL server 【发布时间】:2019-03-15 22:38:09 【问题描述】:

我正在为一个网络应用做一个简单的概念验证

我想知道如何实现上述目标。

我正在从 SQL Server 的 API 中检索一类项目。类的简单结构是

 public partial class ReqsTest

    public string ID  get; set; 
    public string Requisition  get; set; 
    public Nullable<System.DateTime> DateReqnRaised  get; set; 
    public Nullable<decimal> ReqnValue  get; set; 
    public Nullable<decimal> ApprovedValue  get; set; 
    public decimal Line  get; set; 
    public long INDX  get; set; 
    public string ReqStatus  get; set; 
    public string ReqBackground  get; set; 

我正在使用从服务器返回的数据填充一个 Knockout Observable 数组

我的视图模型代码是

var self = this;
self.reqs = ko.observableArray();
self.error = ko.observable();

var reqsUri = '/api/ReqsTests/';

function ajaxHelper(uri, method, data) 
    self.error(''); // Clear error message
    return $.ajax(
        type: method,
        url: uri,
        dataType: 'json',
        contentType: 'application/json',
        data: data ? JSON.stringify(data) : null
    ).fail(function (jqXHR, textStatus, errorThrown) 
        self.error(errorThrown);
    );


function getAllReqs() 
    ajaxHelper(reqsUri, 'GET').done(function (data) 
        self.reqs(data);
    );

问题当然是我现在知道数组中的底层对象属性是不可观察的,就像这个问题here

我正在尝试了解如何使用此代码 here 来弥补差距,但我完全理解这些调用

我相信我需要这种函数来创建具有 Observable 属性的对象,以便以后更新,例如这样的

function Item(ID, Requistion,DateReqnRaised,ReqnValue,ApprovedValue,Line,INDX,ReqStatus,ReqBackground) 
    //Not editable properties
    this.ID = ID; 
    this.Requistion = Requistion;//Not editable
    this.DateReqnRaised = DateReqnRaised;//Not editable
    this.ReqnValue = ReqnValue; //Not editable
    this.Line = Line;
    this.INDX = INDX;



    //editable later properties
    this.ApprovedValue = ko.observable(ApprovedValue); 
    this.ReqStatus = ko.observable(ReqStatus);
    this.ReqBackground = ko.observable(ReqBackground);


但这可能还不完全正确,我相信我需要将这里的代码更改为但我不确定如何使用它调用 item 函数。感觉就像我需要循环遍历 data 中的每个返回来调用函数项以将其添加到可观察数组中,但我还不确定。

function getAllReqs() 
    ajaxHelper(reqsUri, 'GET').done(function (data) 
        self.reqs(data);
    );

谁能帮忙

****更新的代码****

Index.cshtml 代码

 <div class="page-header">
    <h1>Chamberlin Requistions</h1>
</div>

<div class="row">

    <div class="col-xs-4">
        <div class="panel panel-default" >
            <div class="panel-heading">
                <h2 class="panel-title">Requistions</h2>
            </div>
            <div class="panel-body panel-info ">
                <ul class="list-unstyled" data-bind="foreach: Reqs">
                    <li>
                        <div  >
                            <strong>
                                <span data-bind="text: reqs().Requisition"></span>
                                : <span data-bind="text: reqs().Line"></span>
                            </strong>
                        </div>

                    </li>
                </ul>
            </div>
        </div>
        <div class="alert alert-danger" data-bind="visible: error"><p data-bind="text: error"></p></div>
    </div> 
</div>

根据要求提供视图模型的更新代码

function ReqsTest(rt) 
rt = rt || ;
var self = this;
self.id = ko.observable(rt.ID || 0);
self.requisition = ko.observable(rt.Requisition || "");
self.dateReqnRaised = ko.observable(rt.DateReqnRaised || null);
self.reqnValue = ko.observable(rt.ReqnValue || null);
self.approvedValue = ko.observable(rt.ApprovedValue || null);
self.line = ko.observable(rt.Line || 0.00);
self.indx = ko.observable(rt.INDX || 0);
self.reqStatus = ko.observable(rt.ReqStatus || "");
self.reqBackground = ko.observable(rt.ReqBackground || ""); 

function ReqsViewModel ()
var self = this;
self.Reqs = ko.observableArray([]);
self.error = ko.observable();

var reqsUri = '/api/ReqsTests/';

function ajaxHelper(uri, method, data) 
    self.error(''); // Clear error message
    return $.ajax(
        type: method,
        url: uri,
        dataType: 'json',
        contentType: 'application/json',
        data: data ? JSON.stringify(data) : null
    ).fail(function (jqXHR, textStatus, errorThrown) 
        self.error(errorThrown);
    );


function getAllReqs() 
    ajaxHelper(reqsUri, 'GET').done(function (data) 
        // Build the ReqsTest objects
        var reqs = ko.utils.arrayMap(data, function (rt) 
            return new ReqsTest(rt);
        );
        self.Reqs(reqs);
    );


// Load the reqs - Take this out if you don't want it
getAllReqs(); 

//Details
self.detail = ko.observable();

self.getReqDetail = function (item) 
    ajaxHelper(reqsUri + item.INDX, 'GET').done(function (data) 
        self.detail(data);
    );
     
ko.applyBindings(new ReqsViewModel());

谢谢

【问题讨论】:

看起来您在循环遍历数据中返回的每个元素方面走在了正确的轨道上。你试过了吗?哪个部分不工作? 还没试过,我得去谷歌找代码模板。 【参考方案1】:

首先为您的 ReqsTest 类创建一个匹配的 javascript 函数。

function ReqsTest(rt) 
    rt = rt || ;
    var self = this;
    self.id = ko.observable(rt.ID || 0);
    self.requisition = ko.observable(rt.Requisition  || "");
    self.dateReqnRaised = ko.observable(rt.DateReqnRaised || null);
    self.reqnValue  = ko.observable(rt.ReqnValue  || null);
    self.approvedValue = ko.observable(rt.ApprovedValue || null);
    self.line = ko.observable(rt.Line || 0.00);
    self.indx = ko.observable(rt.INDX || 0);
    self.reqStatus = ko.observable(rt.ReqStatus || "");
    self.reqBackground = ko.observable(rt.ReqBackground  || "");

然后制作一个视图模型来绑定到页面。

function ReqsViewModel 
    var self = this;
    self.reqs = ko.observableArray([]);
    self.error = ko.observable();

    var reqsUri = '/api/ReqsTests/';

    function ajaxHelper(uri, method, data) 
        self.error(''); // Clear error message
        return $.ajax(
            type: method,
            url: uri,
            dataType: 'json',
            contentType: 'application/json',
            data: data ? JSON.stringify(data) : null
        ).fail(function (jqXHR, textStatus, errorThrown) 
            self.error(errorThrown);
        );
    

    function getAllReqs() 
        ajaxHelper(reqsUri, 'GET').done(function (data) 
            // Build the ReqsTest objects
            var reqs = ko.utils.arrayMap(data, function(rt) 
                return new ReqsTest(rt);
            );
            self.reqs(reqs);
        );
    

    // Load the reqs - Take this out if you don't want it
    getAllReqs();

并将视图模型绑定到页面...

ko.applyBindings(new ReqsViewModel());

您现在有了一个具有可观察属性的可观察对象数组。

我手动输入了这段代码,所以可能有一些语法错误

【讨论】:

您好,我认为绑定现在需要更新。当我构建项目时,我得到一个网页错误 reqs is undefined。我相信这来自我现在添加到问题底部的 index.cshtml 文件 请发布您的视图模型的 JavaScript 和 ko.applyBindings 代码。 您好,您是要我写一个新问题还是添加到原来的问题? data-bind="foreach: reqs" 应该是 data-bind="foreach: Reqs"reqs 属性的大小写已更改。 嗨@DaveB,很抱歉我没有得到这个。我已经更新了 foreach 代码,它现在可以工作了,但是当我尝试使用绑定到 &lt;span data-bind="text: reqs().Requisition"&gt;&lt;/span&gt;: &lt;span data-bind="text: reqs().Line"&gt;&lt;/span&gt; 中的底层属性时,我得到了 Line: 3391 Error: 'reqs' is undefined 我已经尝试了 Reqs().Requisition,但没有任何乐趣。

以上是关于KnockoutJS - 可观察对象的可观察数组,包含来自 SQL 服务器的数据的主要内容,如果未能解决你的问题,请参考以下文章

可观察到的数组更改不会反映在第一次点击 - KnockoutJS

KnockoutJS:模板未在可观察数组更改时更新(仅在添加时,在删除时有效)

KnockoutJS调用可观察的属性

使用可观察数组进行 Knockoutjs 映射和验证

可观察数组的可观察对象?

以角度声明对象的可观察数组