无法理解为什么$ broadcast无法正常工作

时间:2015-02-13 11:58:44

标签: angularjs coffeescript

我有一个名为'mainApp'的模块。在我的'mainApp'中,我创建了'MainCtrl',并在其上注入'appState'服务。它用于保存将在其他模块和许多控制器中使用的一些全局信息。

在我的'myApp'模块中,我将另一个模块声明为依赖,我称之为'keyboardShortcuts',我在其中创建了一个控制键盘事件的指令。

angular.module "mainApp"
  .controller "MainCtrl", ['$rootScope','$scope','mensagemFactory','appState',($rootScope,$scope,mensagemFactory,appState) ->

    $rootScope.$watch () ->
      appState.getPointer 'actualScreenState'
    , (newValue, oldValue) ->
      console.log 'got here'
      $rootScope.$broadcast 'screenState.changed'
      undefined

    $scope.consoleProcessos = () ->
      mensagemFactory.getMensagens()
        .then (data) ->
          console.log 'processos: ' , data
        ,(error) ->
          console.log 'erro: ', error

    $scope.title = appState.getProp 'actualScreenState','title'

    $rootScope.$on 'screenState.changed' , ->
      $scope.title = appState.getProp 'actualScreenState','title'

    $rootScope.$on 'keyboardShortcut.undo' , () ->
      appState.undo 'actualScreenState'
    $rootScope.$on 'keyboardShortcut.redo' , () ->
      appState.redo 'actualScreenState'

    undefined
  ]

这是我的appState代码

angular.module "mainApp"
  .factory "appState" , [() ->
    return new AppState()
  ]

cloneObject = (obj) ->
  if obj is null or typeof obj isnt 'object'
    return obj
  temp = obj.constructor()
  for key of obj
    temp[key] = cloneObject obj[key]
  return temp

class AppState

  storage = {
    actualScreenState: [{
      subject: 'AtosSuite'
    }]
  }

  pointers = {
    actualScreenState:0
  }

  historyStorage = {

  }

  window.storager = storage
  window.pointers = pointers

  getPointer: (collection)->
    return pointers[collection]

  undo: (collection) ->
    if storage[collection] isnt undefined and pointers[collection] isnt undefined
      if pointers[collection] > 0
        pointers[collection] -= 1
        return true
      return false
    else
      return false

  redo: (collection) ->
    if storage[collection] isnt undefined and pointers[collection] isnt undefined
      if pointers[collection] - 1 <= storage[collection].length
        pointers[collection] += 1
        return true
      else
        return false
    else
      return false

  getCollect: (collection) ->
    if storage[collection] isnt undefined
      pointer = pointers[collection] or 0
      return storage[collection][pointer]
    else
      return false

  setNewCollect: (collection) ->
    if storage[collection] isnt undefined
      return false
    else
      pointers[collection] = 0
      storage[collection] = {}
      return true

  getProp: (collection,prop)->
    if storage[collection] isnt undefined
      pointer = pointers[collection] || 0
      return storage[collection][pointer][prop]
    else
      return false

  setProp: (collection,properties,values)->
    if storage[collection] isnt undefined
      if pointers[collection] is undefined
        pointers[collection] = storage[collection].length-1
      pointer = pointers[collection] || 0
      storage[collection] = storage[collection].slice 0,pointer+1
      tempObject = cloneObject storage[collection][pointer]
      if typeof properties is 'object'
        for property,index in properties
          tempObject[property] = values[index]
      else
        tempObject[properties] = values
      storage[collection].push tempObject
      pointers[collection] += 1
      return true
    else
      return false

我控制键盘事件的指令如下:

angular.module "keyboardShortcuts"
  .directive 'globalDirective' , ['$rootScope','$document','$log',($rootScope,$document,$log) ->
    {
      restrict: 'A',
      link: () ->

        $document.bind 'keypress' , (event) ->
          if event.keyCode is 26
            $rootScope.$broadcast 'keyboardShortcut.undo'
          if event.keyCode is 25
            $rootScope.$broadcast 'keyboardShortcut.redo'
    }
  ]

这是我使用我的服务的控制器:

angular.module "mainApp"
  .controller "screenState", ['$rootScope','$scope','appState',($rootScope,$scope,appState) ->

    $scope.possibleStates = [
      'page1',
      'page2',
      'page3',
      'page4'
    ]

    $scope.actualState = 0

    appState.setProp 'actualScreenState' , ['possibleStates','actualState'] , [$scope.possibleStates,0]

    $scope.changeState = (newIndex) ->
      $scope.actualState = newIndex
      appState.setProp 'actualScreenState' , ['actualState','title'] , [$scope.actualState,(appState.getProp 'actualScreenState', 'possibleStates')[$scope.actualState]]
      undefined

    undefined

  ]

问题是:当我使用'screenState'控制器的'changeState'方法时,我的$ watchched对象被更改,它$ broadcast我接收了许多其他控制器的事件。但是,当我触发我的键盘事件时,它被我的指令接收,这改变了我看到的$对象但是我的$ watch函数没有得到它。我可以在我的控制台中检查对象更改,但不知何故我的$ watch事件未被触发。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

$watch只能确定在摘要周期内监控的值是否已更改,而您的按键事件监听器不会导致这种情况发生。

一个简单的解决方案是在keypress事件监听器的末尾调用$rootScope.$digest();。但是,这会在应用程序增长时导致性能问题。