0

我在使用 KnockoutJS 作为框架方面还很陌生,而且我(显然)遇到了一个我无法(或者更有可能是不够熟练)找到的问题。

我有这个产品组,每个产品组都包含一系列产品。现在,我成功地显示了产品组列表和所有产品列表,没有太大问题。我想在用户左键单击包含产品的 div 时增加产品数量,并在用户右键单击包含产品的 div 时减少产品数量。

我已经正确设置了事件处理程序,因为它们被触发和处理而没有任何问题并且数量发生了变化,但我似乎无法让它反映在页面上。

标记:

<div class="viewProductGroup" data-bind="with: productGroupData">
    <h2 data-bind="text: Title"></h2>
    <div class="stickies" data-bind="foreach: Products">
        <div data-bind="click: $root.addProduct, 
                        event: { contextmenu: $root.removeProduct }">
            <span data-bind="text: Title"></span><br />(<span data-bind="text: Quantity"></span>)</div>
    </div>
</div>

JS的摘录:

function StickyExViewModel() {
    var self = this;

    self.productGroupData = ko.observable();

    // Behaviors
    self.addProduct = function (item) {
        item.Quantity++;
    }
    self.removeProduct = function (item) {
        item.Quantity--;
    }
}

ko.applyBindings(new StickyExViewModel());

现在,我确定我不明白某些内容或遗漏了一些接线。你能帮忙吗?

编辑

这是从 WCF 服务获得的 JSON:

{"d":
    {"__type":"ProductGroup:#Stickyex.Services",
     "Created":"\/Date(1373407200000+0200)\/",
     "ID":1,
     "Products":[
        {"__type":"Product:#Stickyex.Services","Code":"0","ID":0,"Quantity":0,"Title":"0"},
        {"__type":"Product:#Stickyex.Services","Code":"1","ID":1,"Quantity":1,"Title":"1"},
        {"__type":"Product:#Stickyex.Services","Code":"2","ID":2,"Quantity":2,"Title":"2"}],
     "Title":"ProductGroup 1"}
}

获取 JSON 数据的代码(在 StickyExViewModel 内):

self.goToProductGroup = function(productGroup) {
    $.get(serviceUrl, { ixProductGroup: productGroup.ID }, function (data) {
        self.productGroupData(data.d);
    });
}
4

4 回答 4

1

我猜 item.Quantity 是可观察的,因此您不能对其使用增量和减量。每个 observable 都是一个函数,因此您必须使用它()来获取或设置值:

// Behaviors
self.addProduct = function (item) {
    item.Quantity(item.Quantity() + 1);
}
self.removeProduct = function (item) {
    item.Quantity(item.Quantity() - 1);
}
于 2013-07-10T09:45:38.960 回答
1

Quantity 属性必须是可观察的。所以在 StickyExViewModel 你将能够做到这一点:

function StickyExViewModel() {
    var self = this;

    self.productGroupData = ko.observable();

    // Behaviors
    self.addProduct = function (item) {
        item.Quantity( item.Quantity()++);
    }
    self.removeProduct = function (item) {
        item.Quantity( item.Quantity()--);
    }
}

通过将 Quantity 转换为 observable,您的 Gui 将在您更改属性时立即刷新。

于 2013-07-10T09:46:18.197 回答
1

我认为您需要对将您的转换productGroupData为可观察对象的方式进行少量修改。

第一:不productGroupData应该是因为它实际上是一个数组。observableArrayobservable
self.productGroupData = ko.observableArray([]);

其次,将您的 JSON 字符串转换为observableArray可以利用KnockoutJS 映射插件的字符串。这将使您的编码变得更好。因此,您可以使用它将 JSON 转换为observableArray

ko.mapping.fromJS(yourJS_Object, {}, self.productGroupData);//in case you have JS object

或者

ko.mapping.fromJSSON(yourJSON_String, {}, self.productGroupData);//in case you have JSON string.

现在请注意,您的所有属性或对象productGroupData都是可观察的,因此要访问它们,您需要使用()

于 2013-07-10T11:31:13.033 回答
0

感谢所有尝试并成功帮助我的人,我得出了最终的解决方案。为了更新 Quantity,我不应该直接绑定到 JSON 对象,而是在 JS 中创建代表 JSON 对象模型的类。

function Product(item) {
    this.ID = item.ID;
    this.Title = item.Title;
    this.Quantity = ko.observable(item.Quantity);
}

function ProductGroup(data) {
    var self = this;
    this.ID = data.ID;
    this.Title = data.Title;
    this.Products = [];
    for (var i = 0; i < data.Products.length; i++) {
        self.Products.push(new Product(data.Products[i]));
    }
}

我获取 JSON 的部分更改为:

self.goToProductGroup = function(productGroup) {
    $.get(serviceUrl, { ixProductGroup: productGroup.ID }, function (data) {
        self.productGroupData($.map(data, function (pg) {
            return new ProductGroup(pg);
        }));
    });
}
于 2013-07-11T07:15:11.610 回答