1

在 Ember.js 中,创建一个对子属性(数组)的变化做出反应的观察者会导致不直观的行为。如果观察者直接观察到数组属性,它不会触发,而如果它观察到同一个属性的绑定,它会按预期工作。

一个简单的例子:

车把:

<script type="text/x-handlebars">
    <b>App.View1.name:</b> {{App.View1.name}} <br />
    <b>App.View2.name:</b> {{App.View2.name}}
</script>

Javascript:

App = Em.Application.create();

// A common dependency for two views
var dependency = Em.Object.create({
    prop: []
});

// Directly observes dependency.prop
App.View1 = Em.View.create({
    dependency: dependency,
    name: "Foo",
    changeName: function () {
        this.set("name", "Bar");
    }.observes("dependency.prop")
});

// Indirectly observes dependency.prop via a binding
App.View2 = Em.View.create({
    dependency: dependency,
    name: "Foo",
    changeName: function () {
        this.set("name", "Bar");
    }.observes("prop"),
    propBinding: "dependency.prop"
});

// Updating the 'prop' property of dependency with an element.
dependency.get("prop").pushObject("An object.");

我在这里把它放在 JSFiddle 上:http: //jsfiddle.net/kbaXG/50/

在这里,App.View1.name不更新(保持“Foo”)而App.View2.name更新(到“Bar”)。

这是预期的行为,并且创建绑定是可接受的解决方法吗?

4

1 回答 1

2

绑定是 Ember.js 中的一个基本概念,所以不要犹豫使用它 :)

如果您为自己创建绑定,则您的示例有效dependency,请参阅http://jsfiddle.net/pangratz666/Gqc7Q/

App = Em.Application.create({
    VERSION: "0.1"
});

App.dependency = Em.Object.create({
    prop: []
});

App.View1 = Em.View.create({
    dependencyBinding: 'App.dependency',
    name: "Foo",
    changeName: function () {
        this.set("name", "Bar");
    }.observes("dependency.prop")
});

App.View2 = Em.View.create({
    dependencyBinding: 'App.dependency',
    name: "Foo",
    changeName: function () {
        this.set("name", "Bar");
    }.observes("prop"),
    propBinding: "dependency.prop"
});

// Updating the 'prop' property of dependency.
dependency.get("prop").pushObject("An object.");

更新

问题是您正在更改数组的内容,而不是数组本身。因此,您必须将观察者路径更改为dependency.prop.@each,请参阅http://jsfiddle.net/pangratz666/3QccA/。但我不知道为什么它使用绑定方法而不是这个方法......你应该在GitHub 上提交一张票。

最后一点,上述使用绑定的解决方案是更像 Ember 的方法......

var dependency = Em.Object.create({
    prop: []
});

App.View1 = Em.View.create({
    dependency: dependency,
    name: "Foo",
    changeName: function () {
        this.set("name", "Bar");
    }.observes("dependency.prop.@each")
});

App.View2 = Em.View.create({
    dependency: dependency,
    name: "Foo",
    changeName: function () {
        this.set("name", "Bar");
    }.observes("prop"),
    propBinding: "dependency.prop.@each"
});

// Updating the 'prop' property of dependency.
dependency.get("prop").pushObject("An object.");
于 2012-05-22T09:41:56.217 回答