【问题标题】:How can I change controller for a view?如何更改视图的控制器?
【发布时间】:2013-05-16 20:50:17
【问题描述】:

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

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

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

说“对象没有方法”

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

回应cmets

我想将逻辑与视图分离。让我描述一下。单击按钮时,与其关联的操作会冒泡到 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 的事件还是计算属性 - 我希望您能详细说明一下。

【问题讨论】:

  • 您能再展示一些代码吗,尤其是您尝试访问控制器的部分?
  • FWIW,大约 80% 的时间我都想使用事件来影响我的观点,我发现我最好有一个属性。
  • 我已经更新了问题
  • 我也不确定是否可以像我一样订阅路由触发的事件。

标签: ember.js


【解决方案1】:

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

// 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}}

【讨论】:

  • 谢谢!我没有注意到您编辑的答案。但是如何从另一个控制器传递status 消息呢?
  • 所以从另一个控制器,指定needs: ['flash'],然后调用set('controllers.flash.status', 'success');set('controllers.flash.status', 'error')
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
相关资源
最近更新 更多