EmberJS Bindings不同步?

时间:2013-09-10 23:22:25

标签: ember.js

我正在将我的代码库从EmberJS-1.0-rc1升级到EmberJS-1.0。

我的许多绑定似乎不再一致同步。语义必定已经改变,但我无法找到我应该做什么,或者我应该做什么!

var Widg = Ember.Object.extend({
    init: function () {
        this._super();

        console.log("aliasToValue is: ", this.get('aliasToValue'));
        if (this.get('aliasToValue') != this.get('value')) {
            throw "This exception doesn't get hit...";
        }

        console.log("Setting value to 'hello world'");
        this.set('value', "hello world");

        // I would expect:
        // this.get('value') == this.get('aliasToValue')
        // but that doesn't seem to work anymore....

        console.log("After settting, aliasToValue is: ", this.get('aliasToValue'));
        if (this.get('aliasToValue') != this.get('value')) {
            throw "Ugh, after setting, they don't match";
        }
    },
    value: "initial value",
    aliasToValueBinding: "value"
});

Widg.create(); // EXCEPTION: "Ugh, after setting, they don't match"

1 个答案:

答案 0 :(得分:0)

当你添加propertyABinding: propertyB时,基本上是ember会为propertyApropertyB创建一个观察者来安排同步(将propertyA的值设置为propertyBsync队列中,反之亦然。因为已安排同步,所以它将在runloop的最后执行。因此,aliasToValue不会改变:

this.set('value', "hello world");
this.get('value'); // return "hello world"
this.get('aliasToValue'); // return "initial value"

您可以以编程方式调用Ember.run.sync()来刷新同步队列。所以这将有效:

this.set('value', "hello world");
this.get('value'); // return "hello world"
Ember.run.sync();   // don't wait for the end of runloop, and make the sync here
this.get('aliasToValue'); // return "hello world"

但是对于您的示例中的这项工作,您需要进行一些更改。在您的情况下,您在init函数中设置属性。但是在init函数中,不会触发观察。因此,不会安排同步。您可以使用on('init')在对象初始化时执行更改:

...
didInit: function() {
   // now the observes will trigger when a property change
}.on('init')
...

您的代码更新如下:

//the application
App = Ember.Application.create();

App.MyObject = Ember.Object.extend({
    didInit: function () {

        console.log("aliasToValue is: ", this.get('aliasToValue'));
        if (this.get('aliasToValue') != this.get('value')) {
            alert( "This exception doesn't get hit..." );
        }

        console.log("Setting value to 'hello world'");
        this.set('value', "hello world");

        // I would expect:
        // this.get('value') == this.get('aliasToValue')
        // but that doesn't seem to work anymore....

        console.log("After settting, aliasToValue is: ", this.get('aliasToValue'));
        Ember.run.sync();
        if (this.get('aliasToValue') != this.get('value')) {
            alert( "Ugh, after setting, they don't match" );
        }
    }.on('init'),
    value: "initial value",
    aliasToValueBinding: "value"
});

App.MyObject.create(); // EXCEPTION: "Ugh, after setting, they don't match"

jsfiddle http://jsfiddle.net/marciojunior/Bk7L9/

当然Ember.run.sync()只是在极少数情况下使用,删除它会使您的模板和属性更新,但是当runloop完成时。我用它来立即看到绑定属性更新。

有关runloop的更多信息,请参阅此答案What is Ember RunLoop and how does it work?