如何使用$ .getJSON获取时编辑observableArray数据?

时间:2013-09-27 14:15:29

标签: javascript json asp.net-mvc-4 knockout.js

我对knockout.js很新,但我到目前为止都喜欢它!我正在写MVC4,并遇到了一些障碍。我有静态数据,但我现在正在使用通过JSON从控制器传递的数据,我不确定如何做到这一点。

最初,我的活动有一个“课程”:

function Activity(context) {
    var self = this;
    self.type = context.type;
    self.name = context.name;
    self.time = ko.observable(context.time);
    self.product = context.product;
    self.item = context.item;
    self.itemAmount = context.itemAmount;

    self.formattedPrice = ko.computed(function () {
        var price = context.netPrice;
        return price ? "$" + price.toFixed(2) : "None";
    });
}

在我的viewmodel中填充了静态数据:

self.activities = ko.observableArray([
        new Activity({ type: 1, name: "John Smith", time: "1 hour", itemAmount: "5", netPrice: 232.16 }),
        new Activity({ type: 1, name: "Jane Doe", time: "2 hours", itemAmount: "7", netPrice: 4812.30 }),
        new Activity({ type: 1, name: "Clark Kent", time: "4 hours", itemAmount: "5", netPrice: 19.09 }),
    ]);

哪个好,我可以使用ko.computed方法来改变我的数据。现在我正在提取数据,我已经将我的代码浓缩为:

function ActivityViewModel() {
    var self = this;
    self.activities = ko.observableArray();
    $.getJSON("Home/ActivityData", self.activities);
}

哪个工作正常,在我的数据绑定字段中,我只是将我的文本调用从它们的变量名称转换为前面带有$ data的数据库记录名称。 - 非常酷而且容易。

问题是我有一个时间字段,我需要通过moment.js“人性化”,所以问题是......如何在JSON后访问self.activities数据并编辑特定字段?

对不起,如果这是一个简单的,但我没有运气找到帮助(我可能没有找到正确的位置)。提前谢谢!

更新


来自服务器获取JSON的数据来自此LINQ查询:

var Data = from m in dataContext.Activities
                   select new 
                   { 
                       Type = m.Type,
                       ClientName = m.ClientName,
                       UserID = m.UserID,
                       ProductsNo = m.ProductsNo,
                       ProductName = m.ProductName,
                       NetPrice = m.NetPrice,
                       Time = System.Data.Linq.SqlClient.SqlMethods.DateDiffSecond(m.RecordCreated, DateTime.Now)
                   };

我需要做的客户端是采用Time变量并在javascript中对它运行一个函数。我假设它已经完成了ko.computed()函数,但是我似乎无法弄清楚如何将Time变量拉入self.activities时将其定位。

1 个答案:

答案 0 :(得分:5)

记住Knockout基于MVVM模式(虽然在我看来它涓涓细流入MV *)

您需要 模型。通常,任何可以在模型内部更改的项目都应该是可观察的。如果类型,名称,产品等...不会改变,那么不要担心它们是可观察的,但如果它们是,请考虑更新它们。

function activityModel(context) {
    var self = this;
    self.type = ko.observable(context.type);
    self.name = ko.observable(context.name);
    self.time = ko.observable(context.time);
    self.product = ko.observable(context.product);
    self.item = ko.observable(context.item);
    self.itemAmount = ko.observable(context.itemAmount);

    self.formattedPrice = ko.computed(function () {
        var price = context.netPrice;
        return price ? "$" + price.toFixed(2) : "None";
    });
}

然后在你的视图模型中,如果你没有使用映射库,你需要迭代结果并为每个成员创建一个对象,成功返回AJAX调用(记住$ .getJSON只是简写AJAX ) -

function activityViewModel() {
    var self = this;
    self.activities = ko.observableArray();
    $.getJSON("Home/ActivityData", function(data) {
      $.each( data, function( key, val ) {
        self.activities.push(new activityModel(data));
      });
    });
}

最后,您需要一个自定义绑定处理程序来以人类可读的方式显示dateTime。您可以在视图模型之前注册 -

ko.bindingHandlers.DateTime = {
    update: function (element, valueAccessor) {
        var value = valueAccessor();
        var date = moment(value());
        var strDate = date.format('MMMM Do YYYY, h:mm:ss a');
        $(element).text(strDate);
    }
};

然后在你的视图中使用它 -

<div data-bind="foreach: activities"> 
    <span data-bind="DateTime: time"></span>
</div>