0

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

当触发事件时,我想更改视图的状态(简单的闪存消息),但我无法访问路由/控制器。我尝试了 withcontextcontroller属性,但部分:

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 的事件还是计算属性 - 我希望您能详细说明一下。

4

1 回答 1

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}}帮助器来渲染 Flash

{{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')

})

对于视图,将警报类型类名绑定到控制器的状态,并添加一个观察者,该观察者将在消息更改时淡入/淡出。您还需要定义 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}}
于 2013-05-17T02:47:14.933 回答