如何更改视图的控制器?

时间:2013-05-16 20:50:18

标签: ember.js

我想听一下应用路由/控制器广播的一些事件。我用 Evented mixin扩展了它们。

当一个事件被触发时,我想改变视图的状态(简单的flash消息)但我无法访问路由/控制器。我尝试使用contextcontroller属性,但是 部分:

this.get('controller').on('someEvent', handler)
// or
this.get('context').on('someEvent', handler)

说“对象没有方法”

如何更改视图的控制器以及格式(字符串,对象)是什么?

回应评论

我想从视图中分离逻辑。让我来形容一下吧。单击一个按钮时,与其关联的操作会冒泡到ApplicationRoute,因为它非常通用:

App.ApplicationRoute = Em.Route.extend Ember.Evented,
  events:
    someAction: ->
      @trigger 'someEvent', 'success'

我还有一个视图 - flash消息,我想在事件被触发时改变它的状态:

App.FlashView = Em.View.extend
  elementId: 'flash'
  classNames: 'alert'

  didInsertElement: ->
    $this = this.$ this

    @get('controller').on('someEvent', (status) ->
    if status is 'success'
      message = "Wow! Success!!"
    else
      message = "Oops! An error has occured!"

    $this
      .removeClass('alert-error alert-success')
      .addClass("alert-#{status}")
      .empty()
      .append(message)
      .show()
      .fadeIn()
      .delay(2000)
      .fadeOut()
  )

实际上我并不介意使用其他技术,因为我对新的和可能更好的解决方案持开放态度。无论是通过Evented mixin的事件还是计算属性 - 我希望你详细说明这个问题。

1 个答案:

答案 0 :(得分:0)

在这种情况下,更改控制器可能没有意义。而是通过现有的控制器使应用程序控制器可用于您的视图。所以:

// From your controller:
  needs: ['application'];

// Now you can access application controller from your view:
this.get('controller.controllers.application').on('someEvent', handler)

如果您不确定要更改哪个控制器,请从您的视图中尝试:

console.log(this.get('controller').toString())

FWIW我的经历与@Luke相同,从视图中使用事件非常罕见。请考虑绑定到flashMessage属性。

更新(基于更新的问题)

好的,这是use-controller-not-events版本的快速草图。对于我没有测试过此代码的任何拼写错误...

首先,在模板中的某处使用{{render}}助手来渲染闪光灯

{{render flash}}

这将在FlashController

的上下文中呈现FlashView

现在定义FlashController

App.FlashController = Ember.Controller.extend({
  status: nil,
  messages: {
    'success': "Wow! Success!!",
    'error': "Oops! An error has occured!"
  },
  message: function() {
    return this.get('messages')[this.get('status')] || nil
  }.property('status')

})

对于视图,将alert-type classname绑定到控制器的状态,并添加一个观察者,只要消息发生变化,该观察者就会fadeIn / fadeOut。您还需要定义css类hidden,以便在设置消息之前警报不可见。

App.FlashView = Ember.View.extend({
  elementId: 'flash',
  classNames: 'alert hidden',
  classNameBindings: ['alertType'],
  alertType: function() {
    if (this.get('controller.status')) {
      return "alert-" + this.get('controller.status')
    }
  }.property('controller.status'),
  messageDidChange: function() {
    this.$().show().fadeIn().delay(2000).fadeOut()
  }.observes('controller.message')
})

对于flash.hbs模板,请务必输出消息

{{message}}