如何将导航栏中的事件绑定/拆分到当前路径中的控制器?

时间:2014-08-31 16:19:53

标签: ember.js

过去几年来自Backbone世界,我想尝试Ember。我想我应该尝试创建一个移动网络应用程序,因为我已经在移动网络/ Backbone中做了大量工作。我正在尝试构建一个全局导航栏,其中有一个显示在某些路径上的“保存”按钮,而我遇到的问题是如何在导航栏中的“保存”按钮上绑定/拆除该点击事件bar到当前路线的控制器。

我有一个/routines/new路线,应用程序会向用户显示一个表单以创建新例程。导航栏展开Ember.Evented并通过trigger调用传播点击事件。在我的App.RoutinesNewRoute中,在didTransition / willTransition个事件中,我手动执行从App.NavigationControllerApp.RoutinesNewController的绑定(其中包含如何保存模型)。

我当前的方法有效,但这意味着在每条路线中我都必须手动进行绑定/拆卸,而且它看起来像很多样板。我还设想了可以利用与当前路线没有直接关系的自动绑定/拆除过程的控制器/组件(即通过模板中的render调用插入控制器)。我感觉就像应该有一个事件,我可以挂钩控制器"进入视图"所以我可以在一个地方写下装订/拆解而不必考虑它,但也许我不理解" Ember"办法。

所以我的问题:什么是从全局控制器(即导航栏)绑定/拆除事件到任何支持DOM中当前视图的任意控制器的最佳方式?


以下是代码:

现在,我有一个App.NavigationController和一个App.NavigationView,它会被渲染到应用程序布局中:

导航控制器

App.NavigationController = Ember.ObjectController.extend Ember.Evented,
  isShowing: false
  showBack: false
  title: ""
  rightButtonTitle: ""

  navigationStyle: (->
    if @get('isShowing')
      ""
    else
      "display: none;"
  ).property('isShowing')

  backStyle: (->
    if @get('showBack')
      ""
    else
      "display: none;"
  ).property('showBack')

  rightButtonStyle: (->
    if @get('rightButtonTitle')
      ""
    else
      "display:none"
  ).property('rightButtonTitle')

  actions:
    rightButtonClick: ->
      @trigger 'right-button'
    backButtonClick: ->
      @trigger 'back-button'
    reset: ->
      @setProperties
        isShowing: false
        title: ""
        rightButtonTitle: ""

App.NavigationView:

App.NavigationView = Ember.View.extend
  templateName: 'navigation'
  actions:
    rightButtonClick: ->
      @get('controller').send('rightButtonClick')
    backButtonClick: ->
      @get('controller').send('backButtonClick')

application.hbs

{{render 'navigation'}}
{{outlet}}

App.RoutinesNewRoute

App.RoutinesNewRoute = Ember.Route.extend
  model: ->
    if routine = @controllerFor('application').get('routine')
      routine
    else
      @store.find('routine').then (routines) =>
        nextDay = routines.content.length + 1

        promise = @store.find('exercise').then (exercises) =>
          exercises = exercises.map (e) ->
            id: e.get('id')
            name: e.get('name')
            weight: e.get('weight')

          routine = @store.createRecord 'routine',
            exercises: exercises
            day: nextDay

          @controllerFor('application').set('routine', routine)
          routine


  actions:
    didTransition: ->
      @_super()
      # This is where I do all the manual event binding
      @controllerFor('navigation').on 'right-button', @, =>
        @controller.save().then =>
          @controllerFor('application').set('routine', null)
        @transitionTo('routines')

      @controllerFor('navigation').on 'back-button', @, =>
        @transitionTo('routines')

      @controllerFor('navigation').setProperties
        isShowing: true
        showBack: true
        title: "New Routine"
        rightButtonTitle: "Save"


    willTransition: ->
      # This is where I do all the manual event teardown
      @_super()
      @controllerFor('navigation').off 'right-button', @
      @controllerFor('navigation').off 'back-button', @
      @controllerFor('navigation').send('reset')

App.RoutinesNewController

App.RoutinesNewController = Ember.ObjectController.extend
  save: -> @get('model').save()

  actions:
    save: -> @save()

1 个答案:

答案 0 :(得分:1)

您可以做的是在mixin中提取“通过导航保存”行为。我对CoffeeScript不是很熟悉所以以下是Javascript和CoffeeScript的混合。

App.SaveableThroughNavigationMixin = Ember.Mixin.create({
  doEventBindings: function() {
    @_super()
    # This is where I do all the manual event binding
    @controllerFor('navigation').on 'right-button', @, =>
      @controller.save().then =>
        @controllerFor('application').set('routine', null)
      @transitionTo('routines')

    @controllerFor('navigation').on 'back-button', @, =>
      @transitionTo('routines')

    @controllerFor('navigation').setProperties
      isShowing: true
      showBack: true
      title: "New Routine"
      rightButtonTitle: "Save"
  }.on('didTransition'),
  doEventTeardowns: function() {
    # This is where I do all the manual event teardown
    @_super()
    @controllerFor('navigation').off 'right-button', @
    @controllerFor('navigation').off 'back-button', @
    @controllerFor('navigation').send('reset')
  }.on('willTransition')
});

然后,对于您想要此行为的每个Route,您都要包含mixin。

App.RoutinesNewRoute = Ember.Route.extend(App.SaveableThroughNavigationMixin, {
  model: function() {
    ...
  }
});

我希望这会有所帮助。