使用{{action}}来定位不同路线中的事件

时间:2013-02-05 18:32:54

标签: ember.js handlebars.js

假设我有一个像

这样的事件的路线
App.FooRoute = Ember.Route.extend({
  events: {
    anAction: function(){
    }
  }
})

如何从另一个路径/控制器的视图中触发它?

<a {{action anAction target='???'}}> a link </a>

2 个答案:

答案 0 :(得分:2)

假设你有这样的路线:

App.Router
  |
  + FooRoute
  |
  + BarRoute

FooRouteBarRoute发送操作意味着什么?用户已转到/foo,因此FooModelFooControllerFooView已初始化,但Bar*尚未初始化。这个动作会做什么?

案例1:行动操纵栏

在这种情况下,BarModel左右是FooRoute的先决条件。解决此问题的最类似Ember的方法是使用嵌套路由:

App.Router.map(function() {
  this.resource('bar', function() {
    this.route('foo');
  }
});

用户转到/bars/123/foo并点击该链接,触发anAction。 Ember会自动在路线层次结构中将该操作冒出来,因此您只需在anAction上定义BarRoute

案例2:行动不需要酒吧

在这种情况下,不需要BarModelanAction做了一些与Foo无关的东西,但与Bar无关。我们可以使用相同的冒泡技巧,但不是在anAction上定义BarRoute,而是在主路由器上定义它。

案例3:行动需要全球对象

假设行动需要“当前用户”。这种情况很像#2,因为你不需要嵌套路由。但是,它确实需要一个全局可寻址的控制器,如App.currentUserController。您可以直接将其指定为target的{​​{1}}。

案例4:您确实想要定位BarController

如果上述选项都不正确,您可以使用{{action}}controllerFor上设置barController属性:

fooController

然后你可以App.FooRoute = Ember.Route.extend({ setupController: function(controller) { var barController = this.controllerFor('bar'); controller.set('barController', barController); } });

摘要

Ember将自动尝试对照控制器的操作,然后冒泡路线层次结构。如果模型依赖于其他模型,则可能需要嵌套路由或全局控制器以确保连接先决条件。

答案 1 :(得分:0)

Ember Docs中所述,您可以使用名为Ember.ViewTargetActionSupport的内置mixin将操作发送到应用中的其他控制器或视图或路线。

处理问题的简单方法如下:

  1. 模板中调用的事件在当前视图中处理
  2. 此视图中混合了Em.ViewTargetActionSupport
  3. 此视图中写入的事件调用this.triggerAction函数,指定您尝试在不同视图/控制器/路径(目标)中调用的操作
  4. 当前模板:

    <a {{action 'actionInView' target='view'}}>Click me</a>
    

    观点:

    App.CurrentView = Em.View.extend(Em.ViewTargetActionSupport, { // Note the mixin
      actions: { // Actions hash
        actionInView: {
          this.triggerAction({ // Without a target this will bubble through the routes
            action: 'theActionToCall', // Name of the action you *actually* want to call
            target: App.TargetController, // Or whatever the name of your target is
          });
        },
      },
    });
    

    目标控制人:

    App.TargetController = Em.ObjectController.extend({
      actions: {
        theActionToCall: {
          // This is where you do the action stuff that you *actually* are trying to do
        },
      },
    });
    

    基本上,名为actionInView的操作除了调用您实际想要但无法访问的操作之外什么也不做,因为它位于应用程序的不同部分。我没有指定目标,那么你可以将动作放在父路线或应用程序路线上,然后它就会被调用。