如何通过单击{{action}}从外部调用Controller上的操作方法,具有相同的行为

EMA*_*DAL 6 ember.js

请看这个代码......

```

            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…
                        }
                    }
                }
            });
Run Code Online (Sandbox Code Playgroud)

```

我想updateData从外面调用BooksController上的动作.

我试过这段代码.

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

它确实有效.但是,在updateData行动中,this是从一个在不同的updateData被称为通过点击{{行动"了updateData"}} books模板.

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

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

我很高兴知道这件事.

(我正在使用Ember.js 1.0.0)

Jer*_*een 10

你可以使用bindjQuery.proxy. bind从版本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') );
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

bind:

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

jQuery.proxy

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

有趣的是,this 似乎没有使用任何一个bindproxy在这个JSBin中.

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

这是一个显示所有这些的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


con*_*tio 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!");
        }
    },
});
Run Code Online (Sandbox Code Playgroud)