【问题标题】:Listening to property changes in view监听视图中的属性变化
【发布时间】:2014-04-23 16:13:34
【问题描述】:

我有一个使用自定义视图的模板(Emblem)。 模板本身是一种简单的形式,必须输入(并因此设置)密码。到目前为止,我一直在使用标准的 Ember.TextField 视图,但是,我决定向用户提供一些有关密码实际有多好的信息。

我创建的自定义视图如下所示:

div.password-strength-view
  Ember.TextField type="password" classNames="form-control" value=view.password placeholder=view.passwordPlaceholder
div.strength-bar class=view.barClass

背后的javascript:

App.PasswordStrengthView = Ember.View.extend({
  templateName: 'views/password-strength-view',

  password: '',
  passwordPlaceholder: '',

  _passwordScore: 0,
  strengthUpdater: function() {
    var calc = function(pw) {
      return ( Math.random() * 4 + 1 ); // TODO: add zxcvbn
    };

    var strength = calc(this.get('password'));
    this.set('_passwordScore', strength);

    return strength;
  }.property('password'),


  barClass: function() {
    var score = this.get('_passwordScore');
    return 'score-' + score;
  }.property('_passwordScore')
});

我现在想根据密码输入的变化更新.strength-bar 的宽度(通过score-x 类完成)。我还希望能够在我的模板中使用视图并将视图的密码属性设置为映射 (1) 到输入的值和 (2) 到控制器的属性。

在我的模板代码中我尝试了这个:

App.PasswordStrengthView#edituser-pw1 password=newPassword passwordPlaceholder="Super secret"

如果我更改控制器中的newPassword 值,它会反映在视图中。视图本身不会注册任何更改。关于如何实现这一点的任何帮助?我听错了财产吗? view.password 也不起作用。

【问题讨论】:

    标签: javascript ember.js ember-data


    【解决方案1】:

    我可以在这里看到两件事:

    首先,您在视图中为绑定添加了一些额外的间接性,我认为这会导致问题。您创建了一个名为strengthUpdater 的计算属性,它具有设置_passwordScore 属性的副作用。 barClass 很可能没有看到 _passwordScore 由于某些运行循环魔法而更新。

    _passwordScore: 0,
    strengthUpdater: function() {
      // ...
      this.set('_passwordScore', strength); // code smell
    
      return strength;
    }.property('password'),
    

    在计算属性函数中更改其他属性通常不是一个好主意。相反,如果您需要 _passwordScorestrengthUpdater 属性值相同,请使用 Ember.computed.alias

    这可以简化为单个计算属性:

    _passwordScore: function() {
      var calc = function(pw) {
        return ( Math.random() * 4 + 1 );
      };
    
      return calc(this.get('password'));
    }.property('password'),
    
    strengthUpdater: Ember.computed.alias('_passwordScore') // if you still need it
    

    我在 jsBin here 中进行了尝试,这解决了您问题中最重要的部分。

    其次,类名应用不正确:

    div.strength-bar class=view.barClass
    

    这就变成了:

    <div class="strength-bar" {{bind-attr class="view.barClass"}}></div>
    

    如您所见,您正在声明一个类属性,然后在同一属性上创建一个绑定。在我的测试中,strength-bar 类被覆盖并且只应用了score-x。你会想要这个:

    <div {{bind-attr class=":strength-bar view.barClass"}}></div>
    

    抱歉,我不确定 Emblem 将如何实现这种语法。

    【讨论】:

    • 谢谢,现在可以完美运行了。我记得在此处看到有关更新其他属性的此类属性的帖子,就像我对strengthUpdater 所做的那样,但我认为您的说法非常合理。为了解决类名问题,我只是将它添加到控制器的返回值中,因为这不需要花哨。再次感谢!
    猜你喜欢
    • 2017-05-16
    • 2023-02-08
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多