首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Knockoutjs中计算在多行项目中使用的预算的剩余预算

如何在Knockoutjs中计算在多行项目中使用的预算的剩余预算
EN

Stack Overflow用户
提问于 2017-02-07 18:18:46
回答 1查看 321关注 0票数 0

我有一个采购订单模型。采购订单包含行项目。行项目有预算。

现在,每当用户从预算下拉列表中选择预算时,使用kncokoutjs,我希望从服务器加载预算余额,然后重新计算该预算的余额,如果项目使用该预算并将其显示在项目下。

我的问题是如何设计模型,以便我可以捕获在项目上选择的预算并计算剩余金额。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-16 03:30:17

为PurchaseOrder、项目和预算创建不同的ViewModels。使用computeds计算金额,并使用computeds处理ui (例如,可能的预算)。

(参见http://knockoutjs.com/documentation/computedObservables.html )

代码片段中的代码示例:(编辑:实现了预算可以多次使用的要求)

代码语言:javascript
复制
// class for a budget
function Budget(purchaseOrder, name, amount) {
  // track the purchaseOrder object to be able to find the budgets that can be used
  var self = this;
  this.purchaseOrder = purchaseOrder
  this.name = name;

  // amount as an observable so it can be updated from the latest server state
  this.amount = ko.observable(amount);

  this.usedByItems = ko.pureComputed(function() {
    var returnValue = 0;
    self.purchaseOrder.items().forEach(function(item) {

      if (item.budget() === self && item.amount()) {
        // note:better type conversion required
        returnValue = returnValue + parseInt(item.amount());
      }


    });
    return returnValue;
  }, this);

  this.remaining = ko.pureComputed(function() {
    return this.amount() - this.usedByItems();
  }, this);

  // use a computed to determine if the budget is used
  // in the final solutions, computed can be used in the budget dropdown to select only unused budgets
  this.used = ko.pureComputed(function() {
    return this.purchaseOrder.isBudgetUsed(this);
  }, this);
}

// class for an item
function Item(purchaseOrder, budget) {

  var self = this;

  // track the purchase order to track the selectable budgets for the dropdown
  this.purchaseOrder = purchaseOrder;

  // computes the selectable budgets
  this.selectableBudgets = ko.pureComputed(function() {
    var returnValue = [];
    self.purchaseOrder.budgets.forEach(function(budget) {
      // add buget if the item's budget is the same, this to prevent budgets
      // magically disappearing from the dropdown
      if (budget === self.budget() || budget.remaining() > 0) {
        returnValue.push(budget);
      }
    });


    return returnValue;
  }, this);

  // computed to habdle a name when a budget is not selected
  this.name = ko.pureComputed(function() {
    if (this.budget()) {
      return this.budget().name;
    } else {
      return "(none)";
    }

  }, this);
  // the related budget
  this.budget = ko.observable(budget);

  // the entered amount
  this.amount = ko.observable();

}


// the main viewmodel
function PurchaseOrderViewModel() {
  // define the budgets, in the final situation it would probably an observable array so more budgets can be added
  this.budgets = [
    new Budget(this, "Budget 1", 20),
    new Budget(this, "Budget 2", 30),
    new Budget(this, "Budget 3", 40)
  ];

  // the items for the purchase order
  this.items = ko.observableArray(
    [
      new Item(this, this.budgets[0]),
      new Item(this, this.budgets[2]),
    ]
  );

  var self = this;



  this.addItem = function() {
    var item = new Item(self);
    self.items.push(item);
  }

  this.remove = function(item) {
    self.items.remove(item);

  }

  // determins if there is an item that uses the budget.
  this.isBudgetUsed = function(budget) {
    var returnValue = false;
    self.items().forEach(function(item) {
      if (item.budget() === budget) {
        returnValue = true;
      }
    });

    return returnValue;
  }
}

ko.applyBindings(new PurchaseOrderViewModel());
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 

<h1>
Items
</h1>
<ul data-bind="foreach:items">
  <li>
    <select data-bind="options:selectableBudgets,optionsText:'name',value:budget,optionsCaption:'(select a budget)'">

    </select>
    <span data-bind="text:name"></span>
    <input data-bind="value:amount" type="number" />
    <a href="javascript:void();" data-bind="click:function(){ $parent.remove($data);}">remove</a>
  </li>
</ul>
<a href="javascript:void();" data-bind="click:addItem">add item</a>

<h1>
Budget
</h1>
<ul data-bind="foreach:budgets">
  <li>

    <span data-bind="text:name"></span> #<span data-bind="text:amount"></span>, used in po:<span data-bind="text:used"></span>, amount used:<span data-bind="text:usedByItems"></span>, remaining:<span data-bind="text:remaining"></span></li>
</ul>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42087216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档