如何在 ember.js 中使用 ObjectProxy 代理原型上的方法?

How to proxy methods on the prototype using ObjectProxy in ember.js?

我有一个简单的 ObjectProxy,我想使调用方法变得简单(呃)。例如,我计划 "proxy" 的对象有一个名为 foo 和 bar 的方法 - 它们将无法直接使用,导致我做这样的事情。

this.get("model").get("content").foo();
this.get("model").get("content").bar();

相反,我更希望 foo 和 bar 的行为就像它们在对象上一样

this.get("model").foo();
this.get("model").bar();

我可以通过在 ObjectProxy 本身上硬编码 foo 和 bar 方法来实现这一点(长期)——然后提取内容并像这样手动调用方法 w/apply

  return Ember.ObjectProxy.extend({
        content: function() {
            var filter_value = this.get("filter_value");
            return this.get("source").filterBy("id", filter_value).objectAt(0);
        }.property("source.[]"),
        foo: function() {
            var content = Ember.get(this, 'content');
            return content["foo"].apply(content, arguments);
        },
        bar: function() {
            var content = Ember.get(this, 'content');
            return content["bar"].apply(content, arguments);
        }
    }).create({
        filter_value: id,
        source: store.find(type)
    });

如果我想像这样代理每个 "method" - 我怎样才能以一种不会伤害 ember 已经建立的树的方式设置原型?

我不一定要推荐这个,但如果您不想总是定义函数,这是一个想法。老实说,添加到 ember 中并不是一个糟糕的想法,我讨厌必须深入两层才能实现功能。

代码更改

Ember.ObjectProxy.reopen({
  addFunc: function (content, method) {
    this[method] = function () {
      if (!content[method]) return;
      return content[method].apply(content, arguments);
    };
  },
  setupMethods: Ember.observer('content', function () {
    var content = this.get('content');

    if (!content) return;

    for (var item in content) {
      if (typeof content[item] == "function") {
        if (!this[item]) { // watch out for clashing names
          this.addFunc(content, item);
        }
      }
    }
  })
});

我认为跟踪添加的方法,并可能在内容更改后进行清理并不是一件可怕的事情,但我怀疑单个对象代理通常持有多个底层对象。

例子

var o = Ember.ObjectProxy.create();

console.log(o.foo);

o.set('content', {
  foo: function(){
    console.log('hello');
  }
});

console.log(o.foo);

o.foo();

o.set('content',{
  bar: function(){
    console.log('bar');
  }
});

o.bar();

示例:http://emberjs.jsbin.com/juwomezape/1/edit

需要注意的是,在定义内容之前,不存在任何方法,但通常我们甚至在开始处理对象之前就已经解析了对象。