6

请看这段代码...

```

            App.BooksRoute = Ember.Route.extend({
                model:  return function () {
                    return this.store.find('books');
                }
            });

            App.BooksController = Ember.ArrayController.extend({
                actions: {
                    updateData: function () {
                        console.log("updateData is called!");
                        var books = this.filter(function () {
                            return true;
                        });
                        for(var i=0; i<books.length; i++) {
                            //doSomething…
                        }
                    }
                }
            });

```

我想updateData从外部调用 BooksController 上的操作。

我试过这段代码。

App.__container__.lookup("controller:books").send('updateData');

它确实有效。但是,在该updateData操作中,与通过单击模板上的 {{action 'updateData'}} 调用的操作this不同。updateDatabooks

在点击 {{action 'updateData'}} 的情况下,操作中的this.filter()方法updateData将返回书籍模型。但是,在调用的情况下App.__container__.lookup("controller:books").send('updateData');,执行中的this.filter()方法updateData不会返回任何内容。

如何updateData从外部调用 BooksController 上的操作,通过单击 {{action 'updateData'}} 具有相同的行为。

我将不胜感激。

(我使用的是 Ember.js 1.0.0)

4

3 回答 3

11

您可以使用bindjQuery.proxybind从 1.8.5 版本开始在 JS 中提供,因此使用起来非常安全,除非您需要支持非常旧的浏览器。 http://kangax.github.io/es5-compat-table/

无论哪种方式,您基本上都是手动确定this对象的范围。

所以,如果你有这个IndexController,并且你想raiseAlert从应用程序外部触发。

App.IndexController = Ember.ArrayController.extend({
  testValue : "fooBar!",
  actions : {
    raiseAlert : function(source){
      alert( source + " " + this.get('testValue') );
    }
  }
});

bind

function externalAlertBind(){
  var controller = App.__container__.lookup("controller:index");
  var boundSend = controller.send.bind(controller);
  boundSend('raiseAlert','External Bind');
}

jQuery.proxy

function externalAlertProxy(){
  var controller = App.__container__.lookup("controller:index");
  var proxySend = jQuery.proxy(controller.send,controller);
  proxySend('raiseAlert','External Proxy');
}

有趣的是,不使用任何一个或在这个 JSBin 中this 似乎都可以。bindproxy

function externalAlert(){
  var controller = App.__container__.lookup("controller:index");
  controller.send('raiseAlert','External');
}

这是一个显示所有这些的 JSBin:http: //jsbin.com/ucanam/1080/edit

[更新]:另一个调用filter动作的 JSBin:http: //jsbin.com/ucanam/1082/edit

[更新 2]:我通过查找"controller:booksIndex"而不是"controller:books-index".

这是一个 JSBin:http: //jsbin.com/ICaMimo/1/edit

以及查看它的方式(因为路线很奇怪):http: //jsbin.com/ICaMimo/1#/index

于 2013-09-18T04:50:09.097 回答
5

这解决了我的类似问题

在此处阅读有关动作冒泡的更多信息:http: //emberjs.com/guides/templates/actions/#toc_action-bubbling

SpeedMind.ApplicationRoute = Ember.Route.extend({
    actions: {
        // This makes sure that all calls to the {{action 'goBack'}}
        // in the end is run by the application-controllers implementation
        // using the boubling action system. (controller->route->parentroutes)
        goBack: function() {
            this.controllerFor('application').send('goBack');
        }
    },
};

SpeedMind.ApplicationController = Ember.Controller.extend({
    actions: {
        goBack: function(){
            console.log("This is the real goBack method definition!");
        }
    },
});
于 2014-01-15T05:17:03.420 回答
2

You could just have the ember action call your method rather than handling it inside of the action itself.

App.BooksController = Ember.ArrayController.extend({
            actions: {
                fireUpdateData: function(){
                    App.BooksController.updateData();
                }
            },

            // This is outside of the action
            updateData: function () {
                    console.log("updateData is called!");
                    var books = this.filter(function () {
                        return true;
                    });
                    for(var i=0; i<books.length; i++) {
                        //doSomething…
                    }
                }
        });

Now whenever you want to call updateData(), just use

App.BooksController.updateData();

Or in the case of a handlebars file

{{action "fireUpdateData"}}
于 2013-11-10T10:35:09.543 回答