在Ember.js中绑定两个任意对象

时间:2012-03-14 10:51:26

标签: ember.js

我无法理解Ember.js中双向绑定的语法

我有两个想要绑定的对象,这是我尝试过的:

App = Ember.Application.create({});

App.MyPoint = Ember.Object.extend({
    x: 0,
    y: 0,
    init: function()
    {  
    }
});

App.PointView = Ember.Object.extend({
    point: null,
    cx: 0,
    cy: 0,
    init: function()
    {  
    }
});


var aPoint = App.MyPoint.create();

var aPointView = App.PointView.create({point: aPoint, cxBinding: "aPoint.x", cyBinding: "aPoint.y"});

console.log("Expect 0, 0: ", aPointView.get('cx'), aPointView.get('cy'));

aPoint.set('x', 10);
console.log("Expect 10, 0: ", aPointView.get('cx'), aPointView.get('cy')); // But I get 0, 0 ...

jsfiddle:http://jsfiddle.net/W9qtF/

理想情况下,我甚至更喜欢在PointView init()中创建绑定,以便PointView.create({point:aPoint})正确设置所有内容。这可能吗?

4 个答案:

答案 0 :(得分:3)

我已经创建了一个JSFiddle,您可以在其中使用绑定,请参阅http://jsfiddle.net/hVGwV/。我在示例中调用Ember.run.sync()以强制所有绑定立即同步。

<强> JavaScript的:

var get = Ember.get;
var view;
var point;

var flushAndDebug = function(msg) {
    if (msg) { console.log(msg);  }
    Ember.run.sync();
    point.debug();
    view.debug();
    console.log('--------------');
};

Point = Ember.Object.extend({
    x: 0,
    y: 0,
    debug: function() {
        console.log('point: %@/%@'.fmt(get(this, 'x'), get(this, 'y')));
    }
});

PointView = Ember.Object.extend({
    point: null,
    cxBinding: 'point.x',
    cyBinding: 'point.y',
    debug: function() {
        console.log('view: %@/%@'.fmt(get(this, 'cx'), get(this, 'cy')));
    }
});

point = Point.create();
view = PointView.create();

flushAndDebug('point and view created');

view.set('point', point);
flushAndDebug('after point has been set on view');

point.set('x', 50);
flushAndDebug('x of point has been updated');

view.set('cy', 100);
flushAndDebug('y of view has been updated');

view.set('point', null);
flushAndDebug('point of view is set to null');

view.set('cx', '200');
flushAndDebug('x of view is updated');

view.set('point', point);
flushAndDebug('point has been reassigned to view');

var newPoint = Point.create({
    x: 400,
    y: 400
});
view.set('point', newPoint);
flushAndDebug('new created point has been set as point on view');

point.set('x', 42);
flushAndDebug('original point has been updated');

<强>输出:

point and view created
point: 0/0
view: (null)/(null)
--------------
after point has been set on view
point: 0/0
view: 0/0
--------------
x of point has been updated
point: 50/0
view: 50/0
--------------
y of view has been updated
point: 50/100
view: 50/100
--------------
point of view is set to null
point: 50/100
view: (null)/(null)
--------------
x of view is updated
point: 50/100
view: 200/(null)
--------------
point has been reassigned to view
point: 50/100
view: 50/100
--------------
new created point has been set as point on view
point: 50/100
view: 400/400
--------------
original point has been updated
point: 42/100
view: 400/400
--------------

答案 1 :(得分:0)

Ember依赖于一些惯例。其中之一是所有对象/类应位于同一应用程序命名空间下。即类似于window.App = Ember.Application.create()

我将你的例子改写为生活在同一名称空间下 - 然后它起作用:

http://jsfiddle.net/phGeP/1/

App = Ember.Application.create();

App.MyPoint = Ember.Object.extend({
    x: 0,
    y: 0
});

App.PointView = Ember.Object.extend({
    point: null,
    cxBinding: "point.x",
    cyBinding: "point.y"
});


App.aPoint = App.MyPoint.create();

App.aPointView = App.PointView.create({point: App.aPoint});

console.log("Expect 0, 0: ", App.aPointView.get('cx'), App.aPointView.get('cy'));

App.aPoint.set('cx', 10);
console.log("Expect 10, 0: ", App.aPointView.get('cx'), App.aPointView.get('cy'));
​

答案 2 :(得分:0)

这是一个有效的版本:

MyPoint = Ember.Object.extend({
    x: 0,
    y: 0
});

PointView = Ember.Object.extend({
    point: null,

    cx: function() {
        return this.point.x;
    }.property('point'),

    cy: function() {
        return this.point.y;
    }.property('point')
});

aPoint = MyPoint.create();

aPointView = PointView.create({
    point: aPoint
})

console.log("Expect 0, 0: ", aPointView.get('cx'), aPointView.get('cy'));

aPoint.set('x', 10);
console.log("Expect 10, 0: ", aPointView.get('cx'), aPointView.get('cy')); // But I get 0, 0 ...

我改变了cx&amp; cy属性根据当前点的值计算。

然后,当您更改aPoint的值时,必须使用x属性,因为cx是PointView的属性。

答案 3 :(得分:0)

这是一个双向示例:

模板:

<script type="text/x-handlebars" data-template-name="point-view">
    Point: ({{point.x}}, {{point.y}})

    <p>

    {{view Ember.TextField valueBinding="point.x"}}
    {{view Ember.TextField valueBinding="point.y"}}
    {{#view Ember.Button target="App.pointController" action="resetCoordinates"}}Reset coordinates{{/view}}
</script>

JS:

App = Ember.Application.create()

App.Point = Ember.Object.extend({
    x: 0,
    y: 0,

    reset: function() {
        this.set('x', 0);
        this.set('y', 0);
    }
});

App.PointView = Ember.View.extend({
    templateName: 'point-view',
    pointBinding: 'App.pointController.point'
});

App.pointController = Ember.Object.create({
    point: null,

    init: function() {
        this.set('point', App.Point.create());
    },

    resetCoordinates: function() {
        this.point.reset();
    }
})

App.PointView.create().append();