如何实现 emit 以同步方式工作



我正在尝试使用角度$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 块完成的。结果 模型加载总是变得错误。这可能是一个异步问题。

欢迎所有建议。

也许不要使用$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   |
          ---  ---  --- ---
          |  | |  | | | | |

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

  1. 1 如何与 3 对话?

在文件一中.js

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

在文件三中.js

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

在文件二中.js

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

在文件三中.js

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

在文件三中.js

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

在文件一.js&&二中.js要捕获消息的哪个文件

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

在文件二中.js

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

在文件三中.js

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

在文件一中.js

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

然而

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

在父节点中(在本例中为三个... )

所以,在文件三中.js

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

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

注意:在一个嵌套路径中串扰通常很容易,而无需使用$emit、$broadcast或$on,这意味着大多数用例都是当您尝试让 12 通信时,反之亦然。

  1. 2 如何与 1 对话?

在文件二中.js

scope.$emit('pushChangesToAllNodes', sendNewChanges());
function sendNewChanges(){
  return { name: 'talkToOne', data: [1,2,3] };
}

在文件三中.js

We already handled this one remember?

在文件一中.js

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

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

希望这有帮助...

最新更新