角度观察者和事件侦听器以什么顺序执行?

2024-03-30

如果先更改作用域属性,然后再广播事件,那么相应的观察者回调和事件侦听器回调是否总是以相同的顺序执行?例如:

$scope.foo = 3;
$scope.$broadcast('bar');

和其他地方:

$scope.$watch('foo', function fn1(){...});
$scope.$on('bar', function fn2(){...});

Will fn1总是先于执行fn2,反之亦然,或者不能依赖该命令?请引用来源,最好是官方角度文档。

如果重要的话:假设 $scope.foo= 和 $broadcast 发生在 ng-click 调用的函数中(即用户交互)

[旁白]抱歉,问题标题很草率 - 如果您有更好的东西,请重命名。


要了解正在发生的事情,您需要了解 Angular 的$digest https://docs.angularjs.org/api/ng/type/%24rootScope.Scope#%24digest周期和事件$emit 和 $broadcast https://docs.angularjs.org/api/ng/type/%24rootScope.Scope#%24emit功能。

根据一些研究,我还了解到 Angular。 Angular 文档中没有对此进行解释,但可以进行测试(请参阅这个类似问题的答案 https://stackoverflow.com/questions/23460025/when-digest-cycle-is-called#answer-23460476).

把所有这些放在一起,我写了一个简单的实验 https://jsfiddle.net/a0d0ud2o/2/并得出结论,您可以首先运行事件处理程序,然后再运行手表功能。这是有道理的,因为在摘要循环期间可以连续调用监视函数多次。

下面的代码...

模板.html

<div ng-app="myApp">
  <div watch-foo ng-controller="FooController">
    <button ng-click="changeFoo()">
      Change
    </button>
  </div>
</div>

脚本.js

angular.module('myApp', [])
  .directive('watchFoo', watchFooDirective)
  .controller('FooController', FooController);

function watchFooDirective($rootScope) {
  return function postLink(scope) {
    scope.$watch(function () {
        return scope.foo;
    }, function (value) {
        console.log('scope.$watch A');
    });
    scope.$on('foo', function (value) {
        console.log('scope.$on A');
    });
    $rootScope.$on('foo', function (value) {
        console.log('$rootScope.$on A');
    });
    $rootScope.$on('foo', function (value) {
        console.log('$rootScope.$on B');
    });
    scope.$on('foo', function (value) {
        console.log('scope.$on B');
    });
    scope.$watch(function () {
        return scope.foo;
    }, function (value) {
        console.log('scope.$watch B');
    });
  };
}

function FooController($scope) {
  $scope.foo = 'foo';
  $scope.changeFoo = function() {
    $scope.foo = 'bar';
    $scope.$emit('foo');
  };
}

...单击“更改”按钮时,控制台中会产生以下结果:

scope.$on A
scope.$on B
$rootScope.$on A
$rootScope.$on B
scope.$watch A
scope.$watch B

UPDATE

这是另一个测试,说明了监视回调在摘要循环中被调用两次,但事件处理程序没有被第二次调用:https://jsfiddle.net/sscovil/ucb17tLa/ https://jsfiddle.net/sscovil/ucb17tLa/

第三个测试在 watch 函数内发出一个事件,然后更新正在监视的值:https://jsfiddle.net/sscovil/sx01zv3v/ https://jsfiddle.net/sscovil/sx01zv3v/

在所有情况下,您都可以依赖在监视函数之前调用的事件侦听器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

角度观察者和事件侦听器以什么顺序执行? 的相关文章

  • 通过pm2运行node.js,但经常重新启动:通过信号[SIGINT]以代码[0]退出

    我试图在我的系统上运行 node js 但遇到了这个问题 2016 06 01 20 46 28 App app with id 13 and pid 12633 exited with code 0 via signal SIGINT 2
  • 仅单击 div 内部

    我正在为一个小网站制作教程 我只想让教程气泡可点击 因此 当我们尝试单击气泡之外的某些内容时 什么也不会发生 换句话说 我希望我的 html 不可点击 而 tutorial bubble 可点击 尝试这个 jQuery function h
  • 打开 md-calendar 时滚动到当前日期

    目前正在构建一个使用 Angular Material 的应用程序 我们需要一个 md calendar 组件 我们想要自定义按钮样式和内容 因此不使用普通的 md datepicker 问题是 当 md calender 打开时 滚动位置
  • 了解 sort() 比较函数

    我正在使用一个电子商务平台 该平台无法重新排序产品属性字段的选项 这真的很糟糕 因为要插入新选项 您几乎必须删除所有现有选项并重新开始 我正在尝试在客户端进行操作 这是我正在处理的内容 这是针对鞋码的 9 EE 9 1 2 EE 10 EE
  • 在鼠标光标位置添加 cytoscape 节点

    我想在画布上的单击事件上的鼠标箭头位置添加一个 cytoscape 节点 我怎样才能做到这一点 我的方法 效果不太好 我可以通过单击创建一个节点 但无法确保创建的节点的位置位于我单击的位置 使用这样的东西 cy click function
  • 启用/禁用由用户输入确定的复选框

    我有一个简单的表单 用户可以在其中输入他的联系号码 如果联系号码以 07 开头 则该复选框已启用 其他我需要禁用它的复选框 我已经编写了一些代码 但我面临的问题是 当用户键入 01 时 它会被禁用 但如果他们继续在 01 之后添加任何其他数
  • 将文本大小调整为矩形 在 Canvas HTML5 中调整大小

    我是 Canvas 新手 我正在创建一个网站 以在调整矩形大小时增加文本 我尝试了很多 但没有任何效果 实际上 我希望如果我仅按其宽度调整矩形大小 向左拉伸 向右拉伸 则仅应增加文本宽度而不是字体大小 我已经完成了字体大小 但发现增加孤立文
  • 如何在 HTML / Javascript 页面中插入 PHP 下拉列表

    好吧 这是我的第二篇文章 请接受我是一个完全的新手 愿意学习 花了很多时间在各个网站上寻找答案 而且我几乎已经到达了我需要到达的地方 至少在这一点上 我有一个网页 其中有许多 javascript 函数 这些函数一起使用 google 地图
  • 有没有办法将变量从 javascript 导入到 sass 或反之亦然?

    我正在制作一个依赖于块概念的 CSS 网格系统 所以我有一个基本文件 例如 max columns 4 block width 220px block height 150px block margin 10px 它被 mixin 使用 m
  • 在管道中重用变量的功能方式

    在 javascript 和 typescript 中与 Ramda 一起使用函数式编程 我经常发现自己编写如下代码 const myFun c gt const myId c id const value pipe getAnotherO
  • 在 React Navigation 中将 props 传递给自定义抽屉导航器

    在反应导航抽屉菜单中 我想显示用户名 John Doe 它处于我的主要组件的状态 Router 我怎样才能将自定义抽屉内容组件传递给它 额外信息 我从 AsyncStorage 中获取此名称 组件已挂载 这是我的代码 export defa
  • 在 Fabric.js 中按宽度/高度在另一个画布对象内居中和缩放画布对象

    Goal 将一个对象 水平和垂直 置于另一个对象 矩形或组 的中心canvas via Fabric js或者通过Javascript保持原始对象的长宽比相同 但也不超过父对象的宽度 高度比例 父对象 矩形或组 不会居中于canvas元素
  • 在 angularjs 应用程序中更改页面的位置哈希,无需重新加载页面

    我需要能够更改页面的位置哈希 例如从 到 page1 以便 angularjs 不会重新加载页面 有可能吗 在路由定义中添加此参数reloadOnSearch false 禁止在查询参数更改时重新加载基于 ui router 的视图 htt
  • 如何使用 vanilla JS 实现可维护的反应式 UI

    今天我遇到了一个问题 可以通过使用像 Vue 这样的反应式和状态管理框架来轻松解决 遗憾的是 无法使用它 以下 简化 情况 链接到代码笔 https codepen io theiaz pen BazErKV 我们有一个服务器渲染的页面 其
  • 获取点击的的DOM路径

    HTML div class lol a class rightArrow href a div 伪代码 rightArrow click function rightArrowParents this dom dom is the pse
  • 如何打开弹出窗口并用父窗口中的数据填充它?

    如何使用 JavaScript jQuery 使用父页面中 JS 变量的数据填充弹出窗口 在我的示例中 我有一个文件名数组 我在父窗口中最多列出五个 如果还有更多 我想提供一个链接来打开弹出窗口并列出数组中的每个帖子 因此 如果我打开一个包
  • 从 DirectionsRenderer 中获取折线或标记的事件

    我正在使用 DirectionsService 和路线方法来生成 DirectionsResult 我还使用 DirectionsRenderer 对象来显示结果 因为它非常易于使用 我在检测 Directions changed 事件时没
  • 使用 AngularJS 多部分表单数据将文件上传到 Google Cloud Storage

    我正在尝试使用 AngularJS 中指定的多部分方法将图像文件上传到 Google Cloud Storagehttps cloud google com storage docs json api v1 how tos upload m
  • JavaScript:测试与执行

    我想知道检查字符串 例如邮件 密码等 的最佳方法是什么 i exec a vs i test a exec返回值 test true test 1 way var mail req body mail if check mail exec
  • MongoDB中如何通过引用字段进行查询?

    我有两个 Mongo 模式 User id ObjectId name String country ObjectId Reference to schema Country Country id ObjectId name String

随机推荐