请查看此代码......
```
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…
}
}
}
});
```
我想从外面调用BooksController上的updateData
操作。
我尝试了这段代码。
App.__container__.lookup("controller:books").send('updateData');
它确实有效。但是,在updateData
操作中,通过点击this
模板上的{{action'updateData'}},updateData
与调用books
的操作不同。< / p>
如果点击{{action'updateData'}},this.filter()
操作中的updateData
方法将返回图书模型。
但是,如果调用App.__container__.lookup("controller:books").send('updateData');
,this.filter()
操作中的updateData
方法将不返回任何内容。
如何通过点击{{action'updateData'}}以相同的行为从外部调用BooksController上的updateData
操作。
我很高兴知道这件事。
(我正在使用Ember.js 1.0.0)
答案 0 :(得分:10)
您可以使用bind
或jQuery.proxy
。自1.8.5版本以来,JS中提供了bind
,因此除非您需要支持非常旧的浏览器,否则使用起来非常安全。 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');
}
有趣的是this
似乎没有在此JSBin中使用bind
或proxy
。
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
答案 1 :(得分: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!");
}
},
});
答案 2 :(得分:2)
你可以让ember动作调用你的方法,而不是在动作本身内部处理它。
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…
}
}
});
现在,只要您想调用updateData(),只需使用
即可App.BooksController.updateData();
或者是把手文件
{{action "fireUpdateData"}}