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

Mik*_* H. 0 javascript json asp.net-mvc-4 knockout.js

我对knockout.js很新,但到目前为止我都喜欢它!我正在写MVC4,并遇到了一些障碍.我用静态数据得到了kojs,但我现在正在使用通过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";
    });
}
Run Code Online (Sandbox Code Playgroud)

在我的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 }),
    ]);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

UPDATE


来自服务器获取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)
                   };
Run Code Online (Sandbox Code Playgroud)

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

PW *_*Kad 5

Remember Knockout is based on the MVVM pattern (although it trickles into MV*in my opinion)

You need a class model. Generally any item that can change inside the model should be an observable. If type, name, product, etc... won't be changing then don't worry about making them observable, but if they are, consider updating them.

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";
    });
}
Run Code Online (Sandbox Code Playgroud)

Then in your view model, if you are not using a mapping library, you need to iterate through the results and create an object for each one, on the successful return of the AJAX call (remember $.getJSON is just shorthand 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));
      });
    });
}
Run Code Online (Sandbox Code Playgroud)

Last, you need a custom binding handler to show your dateTime in human readable. You can register this before your view model -

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

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

<div data-bind="foreach: activities"> 
    <span data-bind="DateTime: time"></span>
</div>
Run Code Online (Sandbox Code Playgroud)