0

我正在尝试使用角度 $emit 和命令文件在页面加载期间显示微调器。我的模型是:

Model:

    model.load = function(){
        model.loading = true;
        $rootScope.$emit('loadMyPage', model.loading);
        return service.getData().then(storesResult, storesFault);
    }


       var storesResult = function (value) {
        model.categoriesLoading = false;
        $rootScope.$emit('loadMyPage', model.loading);
        model.stores = value.result;
        saveData();
    };

    var storesFault = function (value) {
        var data = value.data;
        var status = value.status;
        model.categoriesLoading = false;
        model.stores = null;
        $rootScope.$emit('loadMyPage', model.loading);
        $rootScope.$emit('systemAlert', {title: 'Loading Error', message: data, status: status, type: 'danger', timeout: 10000, showAsModal: true});
        return value;
    };

在 app.run 中执行的我的命令文件

command.execute = function () {
            $rootScope.$on('loadMyPage', onLoadingChange);
        };

        var onLoadingChange = function (event, value) {
            if (model.loading === true) {
                showModal('sections/modals/loading/loading.tpl.html');
            } else {
                hideModal();
            }
        };
};

问题是在页面加载过程中,来自 model.load 的 $emit 没有转到 $on 命令。当 $on 被调用时,它是从 storesResult 块中完成的。结果 model.loading 总是假的。这可能是一个异步问题。

欢迎所有建议。

4

1 回答 1

0

也许不要使用 $emit 和 $on。如果您有 $rootscope 对象,只需使用您的键值对或您要检查的任何数据创建一个键。您的数据可能如您所愿,或者使用 $watch 等待它,或者只是使用带有 $rootscope 的回调。

Model:

    model.load = function(){
      // model.loading = true;
      $rootScope.isLoading = true;
      return service.getData().then(storesResult, storesFault);
    }


    var storesResult = function (value) {
      model.categoriesLoading = false;
      $rootScope.isLoading = true;
      model.stores = value.result;
      saveData();
    };

    var storesFault = function (value) {
      var data = value.data;
      var status = value.status;
      model.categoriesLoading = false;
      model.stores = null;
      $rootScope.isLoading = true;
      $rootScope.$emit('systemAlert', {title: 'Loading Error', message: data, status: status, type: 'danger', timeout: 10000, showAsModal: true});
    return value;
};

command.execute = function () {
        $rootScope.$watch('isLoading', onLoadingChange);
    };

    var onLoadingChange = function ( value ){
        if (value === true) {
        // or simply if( value )
            showModal('sections/modals/loading/loading.tpl.html');
        } else {
            hideModal();
        }
    };
};

然而

也许 $rootScope 不是用属性污染的最佳主意。我会把那个留给你。

$emit 和 $broadcast 的快速帮助

控制器被实例化,使用 $scope DI'd =>链接 (不是单例);

这就是广播和发射的工作方式。注意下面的节点;全部嵌套在节点 3 中。当您遇到这种情况时,您可以使用广播和发射。

                   3
               --------
              |        |
             ---     ----
            1   |    2   |
          ---  ---  --- ---
          |  | |  | | | | |

看看这棵树。您如何回答以下问题? 注意:还有其他方法,但这里我们将讨论广播和发射。此外,在阅读下面的文本时,假设每个数字都有自己的文件(指令、控制器),例如 one.js、two.js、three.js。

  1. 1如何与3对话?

在文件 one.js 中

scope.$emit('messageOne', someValue(s));

在文件 three.js 中

scope.$on('messageOne', someValue(s));
  1. 2如何与3对话?

在文件 two.js

scope.$emit('messageTwo', someValue(s));

在文件 three.js 中

scope.$on('messageTwo', someValue(s));
  1. 3如何与1和/或2说话?

在文件 three.js 中

scope.$broadcast('messageThree', someValue(s));

在文件 one.js && two.js 中,无论您要捕获消息的哪个文件

scope.$on('messageThree', someValue(s));
  1. 2如何与1对话?

在文件 two.js

scope.$emit('messageTwo', someValue(s));

在文件 three.js 中

scope.$on('messageTwo', function( event, data ){
  scope.$broadcast( 'messageTwo', data );
});

在文件 one.js 中

scope.$on('messageTwo', someValue(s));

然而

当所有这些嵌套的子节点都尝试像这样进行通信时,您将很快看到许多 $on 的 $broadcast 和 $emit 。这是我喜欢做的事情。

在父节点(在这种情况下是三个......)

所以,在文件 three.js

scope.$on('pushChangesToAllNodes', function( event, message ){
  scope.$broadcast( message.name, message.data );
});

现在在任何子节点中,您只需要$emit消息或使用$on捕获它。

注意:不使用 $emit、$broadcast 或 $on 通常很容易在一个嵌套路径中进行串扰,这意味着大多数用例适用于您试图让12通信时,反之亦然。

  1. 2如何与1对话?

在文件 two.js

scope.$emit('pushChangesToAllNodes', sendNewChanges());

function sendNewChanges(){
  return { name: 'talkToOne', data: [1,2,3] };
}

在文件 three.js 中

We already handled this one remember?

在文件 one.js 中

scope.$on('talkToOne', function( event, arrayOfNumbers ){
  arrayOfNumbers.forEach(function(number){
    console.log(number);
  });
});

您仍然需要将 $on 与要捕获的每个特定值一起使用,但现在您可以在任何节点中创建您喜欢的任何内容,而不必担心如何通过父 gap获取消息。

希望这可以帮助...

于 2015-07-10T22:46:01.897 回答