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

これは予想される動作であり、バインディングを作成することは許容できる回避策ですか?

4

1 に答える 1

2

バインディングはEmber.jsの基本的な概念なので、遠慮なく使用してください:)

のバインディングを作成すると、この例は機能します。http ://jsfiddle.net/pangratz666/Gqc7Q/dependencyを参照してください。

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.");

アップデート

問題は、配列自体ではなく、配列の内容を変更していることでした。したがって、オブザーバーパスをに変更する必要があります。http://jsfiddle.net/pangratz666/3QccA/dependency.prop.@eachを参照してください。しかし、なぜそれがバインディングアプローチで機能し、これでは機能しないのかわかりません... 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 に答える