ember对象中仅JS的属性。强制性的东西

时间:2014-04-03 01:19:27

标签: javascript ember.js

我尝试构建一个受google's timer启发的时间输入组件。

这是我的版本:

My version here

我知道有很多方法可以做到这一点,但这个方法最让我困惑。

我选择使用数组shift()/push()到位的最后一位/新数字并保留数组length <= 4

模板:

{{input value=inputValue type="text"}}

<span {{bind-attr class="digits.3::placeholder"}}>{{digits.[3]}}</span>
<span {{bind-attr class="digits.2::placeholder"}}>{{digits.[2]}}</span>
<span {{bind-attr class="digits.2::grey"}}>h</span>

<span {{bind-attr class="digits.1::placeholder"}}>{{digits.[1]}}</span>
<span {{bind-attr class="digits.0::placeholder :last"}}>{{digits.[0]}}</span>
<span {{bind-attr class="digits.0::grey"}}>m</span>

组件:

App.TimeInputComponent = Ember.Component.extend(
  MAX_TIME: 99 * 60 + 59

  didInsertElement: () ->
    if @get('value')
      @set('inputValue', @formatValue(@get('value')))

  classNames: ['time-input-component']
  classNameBindings: ['focused:focused']

  digits: []

  keyUp: (e) ->
    code = e.which
    char = String.fromCharCode(code)
    return unless 48 <= code <= 57 or code == 8 or code == 9

    digits = @get('digits')
    if code == 8
      digits.shift()
    else if char.match(/[0-9]/)
      digits.pop() if digits.length >= 4
      digits.unshift(char)

    # Initial idea: NOT working
    @notifyPropertyChange('digits')

做了一些冗长的调试,发现了这个:

由于MANDATORY_SETTER,对get()的调用仅在对象的meta.values内,而不在属性本身(obj[keyName])内。

所以只是为了测试它,我这样做是为了让组件的this.digits[Ember.META_KEY].values中的值更新:

    @set('digits.0', digits[0])
    @set('digits.1', digits[1])
    @set('digits.2', digits[2])
    @set('digits.3', digits[3])

有没有办法围绕4个set()调用并仍然使用普通数组? 我应该使用ArrayProxy吗?我希望在这个特定的用例中我可以使用普通数组。

1 个答案:

答案 0 :(得分:0)

根据我的经验,如果你发现自己需要深入了解Ember的内部情况以了解正在发生的事情,那么你已经偏离了难以捉摸的“Ember方式”,而Ember将继续与你战斗。正如您所发现的那样,在模板中引用数组中的特定元素并不是Ember真正希望您做的事情。

为什么不给出像hoursTensDigit这样的个别数字名称,而不是继续将数字视为模板中的数组。然后你可以用以下代码替换你的套件:

@set 'hoursTensDigit', digits.objectAt(3)
...

或向组件添加一些计算属性

hoursTensDigit: ( ->
    return digits.objectAt(3)
).property 'digits.@each'
...

您可以继续引用除模板之外的其他任何位置的个别数字(尽管您可能希望使用.objectAt(..)而不是'。[x]'),并且所有内容都应该在游泳中运行。计算出的属性,或者将所有集合放在观察者的“数字。@ each”中,一旦你开始倒计时等,就会给你最大的里程数。