【问题标题】:How to edit observableArray data when fetched with $.getJSON?使用 $.getJSON 获取时如何编辑 observableArray 数据?
【发布时间】:2013-10-03 21:11:07
【问题描述】:

我对 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";
    });
}

在我的视图模型中填充了静态数据:

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 来“人性化”,所以问题是......我如何访问 self.activities 后 JSON 数据并编辑特定字段?

很抱歉,如果这很容易,但我没有运气在这件事上找到帮助(我可能没有找到正确的位置)。提前致谢!

更新


来自服务器获取 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 后如何定位它。

【问题讨论】:

  • 你能创建一个小提琴来显示你的问题吗?
  • 并非如此。无法从 jsfiddle 上的服务器获取 JSON 数据。
  • 是的,您可以从很多来源获取 JSON 数据。您还可以通过从函数返回 JSON 来伪造一个 JSON 调用
  • 酷,不知道。谢谢!

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


【解决方案1】:

记住 Knockout 是基于 MVVM 模式(尽管在我看来它会渗透到 MV* 中)

你需要一个class model。通常,模型内部可以更改的任何项目都应该是可观察的。如果类型、名称、产品等...不会更改,则不必担心使它们可观察,但如果是,请考虑更新它们。

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>

【讨论】:

  • 我觉得这是要走的路,但我希望有一种更优雅的方式来操作可观察数组(不使用模型)。哦,好吧,谢谢...这应该会有所帮助!
  • 如果您不想担心创建模型,请查看 Breeze.js 或 JayData 等数据库
  • @PWKad: self.activities.push(new activityModel(val)); 对吗?
  • 是的,我回答了你的问题,我认为它可以解决你的问题。如果不在那里发表评论,我可以提供帮助
猜你喜欢
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
  • 2020-07-22
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 2020-07-19
  • 1970-01-01
相关资源
最近更新 更多