Ember绑定输入值取决于另一个输入

时间:2018-04-23 04:00:59

标签: javascript ember.js ember-data

我正在研究Ember JS,我有一个奇怪的问题,我找不到解决方案。

现在我有一个表单,在这种形式下,我有一个“成本”输入显然需要 项目的成本,紧挨着它是用户的选择标记 选择输入成本的时间支出。

如果用户每天在指定商品上花费10美元,那么他应该从选择菜单中选择“每日”,如果花费10美元“每周” 用户应选择“每周”等等。

现在在这两个输入的下方,我有四个“只读”标签,我想向用户显示他每天花费多少“每周”“每月”和“每年”。

但是我收到错误“断言失败你修改了****两次......”

这是我的模板:

{{ui-input value=name placeholder="Expense Name" label="Name"}}

{{ui-input value=cost placeholder="Expense Cost" label="Cost" half=true}}

{{ui-select value=costTime default="Expense Time" label="Expense Time" items=formData.expenseTime half=true}}

<div class="col-md-6 no-padding">
    {{ui-readonly value=expense.daily placeholder="Daily" label="Daily" half=true}}
    {{ui-readonly value=expense.weekly placeholder="Weekly" label="Weekly" half=true}}            
</div>
<div class="col-md-6 no-padding">
    {{ui-readonly value=expense.monthly placeholder="Monthly" label="Monthly" half=true}}            
    {{ui-readonly value=expense.yearly placeholder="Yearly" label="Yearly" half=true}}
</div>

这就是我在控制器中尝试做的事情

import Ember from 'ember';
export default Ember.Component.extend({
        expense : { daily: '', weekly: '', monthly: '', yearly: '' },
        setExpense : Ember.computed('cost', 'costTime', 'expense.weekly', function() {
            if (this.get('costTime') == 'daily') {
                this.set('expense.weekly', Number(this.get('cost') * 7))
            }
            return this.get('expense.weekly')
        }),
});

2 个答案:

答案 0 :(得分:1)

我可以看到您正在尝试在计算属性expense.weekly中设置属性setExpense,这被视为反模式,因为在计算的属性中设置属性可能会触发UI重新呈现和它已经被弃用了。而且,根据计算属性(setExpense)中的逻辑,我认为它非常适合于一个动作。

您可以将逻辑移动到单独的操作,并在选择选项更改时触发它。这将消除您现在面临的回溯错误。

<强>替代: 您可以在具有相应依赖属性的computed属性的帮助下计算expense

expense: Ember.computed('cost', 'costTime', function () {
  let expense = { daily: '', weekly: '', monthly: '', yearly: '' };
  // compute the expense here...
  return expense;
})

答案 1 :(得分:0)

最佳模式是使用DDAU和组件didReceiveAttrs钩。

import Ember from 'ember';
export default Ember.Component.extend({
    cost: null,
    costTime: null
    expense : { daily: '', weekly: '', monthly: '', yearly: '' },

    didReceiveAttrs: function() {
        var cost = this.get('cost');
        var costTime = this.get('costTime');
        if (cost && costTime) {
          if (costTime == 'daily') {
            this.set('expense.weekly', Number(cost * 7))
          } else ...
        }
    }
});

并且您必须将有关变更成本和costTime的操作传递给父组件并在那里进行更改。 编辑:另一种方法是定义更多属性:

import Ember from 'ember';

var multipliers = { daily: 1, weekly: 7, monthly: 30, yearly: 365 };
function computeDailyCost(cost, costTime) {
  var multiplier = multipliers[costTime];
  if (multiplier) {
    return cost / multiplier
  }
}

function defMultCost(multiplierKey) {
  return Ember.computed("cost", "costTime", function() {
    var dailyCost = this.computeDailyCost(this.get("cost"), this.get("costTime"));
    var multiplier = multipliers[multiplierKey];
    if (dailyCost != null && multiplier != null) {
      return dailyCost * multiplier;
    }
  });
};

export default Ember.Component.extend({
    cost: null,
    costTime: null
    daily: defMultCost("daily"),
    weekly: defMultCost("weekly"), 
    monthly: defMultCost("monthly"), 
    yearly: defMultCost("yearly")

});

我没有对此进行测试,但它应该有效。