【问题标题】:emberjs two-way-binding temporarily broken after value assignment at init在 init 赋值后,emberjs 双向绑定暂时中断
【发布时间】:2016-05-13 14:52:36
【问题描述】:

我正在尝试在init 生命周期挂钩处为我的一个组件分配默认值;以防从父组件传递未定义的值。最初一切似乎都按预期工作。但是,当我的组件被强制重新渲染时(可能通过父组件的另一个属性值更新);父组件的未定义值被写回我的组件。

这意味着;我在初始化时所做的赋值并没有反映到父组件,也就是说双向绑定暂时不起作用(父子组件的值不同步)。这是预期的行为还是我错过了什么。对 init 事件重要吗?初始化组件的未定义值的合适位置在哪里?请参阅twiddle 以获取简单说明。

【问题讨论】:

  • 问题是当我点击按钮“名称”消失。对吗?
  • 在某种程度上是的。问题是即使我在子组件的init 钩子中设置了 name 属性;该值不会通过与父组件的双向绑定反映出来,并且在下一次重新渲染中,组件的未定义值被写回子组件并且该值消失。 See what happens 以防代码从 init 移动到 didReceiveAttrs

标签: ember.js ember-components


【解决方案1】:

好的,首先一种解决方法是在attr 上使用update 函数。结帐this twiddle

我将.js 中的this.set('name', 'tom') 替换为this.attrs.name.update('tom'),并将.hbs 中的{{name}} 替换为{{attrs.name}}

另一种解决方法是将分配包装在Ember.run.later 中,就像我已经完成的here 一样,我用它替换了this.set('name', 'tom')

Ember.run.later(() => {
  this.set('name', 'tom');
});

这就是解决方法。

在 init 上没有完全设置绑定的事实由来已久。但通常它是一种反模式,用于初始化子组件中的值并将该值交给父组件。它使您的代码可读性降低,并且违反了 DDAU(数据向下,动作向上)原则。

我建议在创建模型时显式初始化数据,而不是在组件评估周期中隐式初始化。

对于您不想存储的默认值,我建议您编写一个计算属性:

nameWithDefault: computed('name', {
    get() {
        return get(this, 'name') || 'tom';
    },
    set(key, val) {
        set(this, 'name', val);
    }
})

这是明确的,在查看组件后不会写下数据,并且适用于用户。

【讨论】:

  • attrs 是什么?你能提供有关它的资源吗?
  • 查看this blog post
【解决方案2】:

我同意 Lux 的解决方案,但如果您想尝试其他方法,也许可以在您的子组件上添加一个计算属性来检查名称或默认为另一个字符串。这允许您在不同的子模板上有不同的默认值(假设您有不同的子组件使用相同的name 属性)。

子组件.js

export default Ember.Component.extend({
  child_name: Ember.computed('name', function() {
    return this.get('name') || 'tom';
  }),
});

子组件.hbs

{{child_name}}
<br>
{{surname}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 2017-08-01
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 2013-05-04
    相关资源
    最近更新 更多