【问题标题】:What is .$on() in AngularJSAngularJS 中的 .$on() 是什么
【发布时间】:2015-03-01 23:12:44
【问题描述】:

我在教程中得到了这个代码$rootScope.$on('abc',function(event, next, current){ });

我的问题是.$on() 是什么?如果是函数,那为什么前面有$

【问题讨论】:

  • 您可以说它是一个函数,因为您使用() 调用它。 $ 基本上没有意义。 Angular 框架的属性只有$,就像$rootScope 一样。它提醒你它基本上来自 Angular。无意义的。 $.on 只是一个附加事件监听器的函数。阅读文档。
  • Check API docs,这里有你需要的所有答案
  • 在我使用 AngularJS 的经验中,$on 与 jQuery 的 on 函数几乎相同。 $ 只是表示它是一个保留的公共 Angular 标识符。
  • @aarosil 谢谢,人们应该做的第一件事就是找到官方文档,我印象深刻的是没有答案给出链接。

标签: angularjs


【解决方案1】:

$on$broadcast$emit 相关——这是一种从其他地方触发代码的方式。

关于$on你首先要知道的是它是$scope的一个方法

您应该知道的第二件事是 $ 前缀指的是 Angular 方法,$$ 前缀指的是您应该避免使用的 Angular 方法。

现在让我们详细了解$on 是什么。

下面是一个示例模板及其控制器,我们将探索$broadcast/$on 如何帮助我们实现我们想要的。

<div ng-controller="FirstCtrl">
    <input ng-model="name"/> 
    <button ng-click="register()">Register </button>
</div>

<div ng-controller="SecondCtrl">
    Registered Name: <input ng-model="name"/> 
</div>

控制器是

app.controller('FirstCtrl', function($scope){
    $scope.register = function(){

    }
});

app.controller('SecondCtrl', function($scope){

});

我的问题是,当用户单击注册时,如何将名称传递给第二个控制器?您可能会想出多种解决方案,但我们要使用的解决方案是使用 $broadcast 和 $on。

$broadcast 与 $emit

我们应该使用哪个? $broadcast 将向下引导到所有子 dom 元素,而 $emit 将反向引导到所有祖先 dom 元素。

避免在 $emit 或 $broadcast 之间做出决定的最佳方法是从 $rootScope 进行通道并将 $broadcast 用于其所有子级。由于我们的 dom 元素是同级的,这使得我们的案例变得更加容易。

添加 $rootScope 并让 $broadcast

app.controller('FirstCtrl', function($rootScope, $scope){
    $scope.register = function(){
        $rootScope.$broadcast('BOOM!', $scope.name)
    }
});

请注意,我们添加了 $rootScope,现在我们使用的是 $broadcast(broadcastName, arguments)。对于广播名称,我们想给它一个唯一的名称,这样我们就可以在我们的 secondCtrl 中捕获该名称。我选择了BOOM!只是为了好玩。第二个参数“arguments”允许我们将值传递给监听器。

接收我们的广播

在我们的第二个控制器中,我们需要设置代码来收听我们的广播

app.controller('SecondCtrl', function($scope){
  $scope.$on('BOOM!', function(events, args){
    console.log(args);
    $scope.name = args; //now we've registered!
  })
});

真的就这么简单。 Live Example

实现类似结果的其他方法

尽量避免使用这套方法,因为它既不高效也不易于维护,但它是解决您可能遇到的问题的简单方法。

您通常可以通过使用服务或简化控制器来做同样的事情。我们不会详细讨论这一点,但我想我只是为了完整起见而提及它。

最后,请记住一个非常有用的广播是“$destroy”,您可以再次看到 $ 表示它是由供应商代码创建的方法或对象。无论如何,当控制器被销毁时会广播 $destroy,您可能想听听这个以了解您的控制器何时被移除。

【讨论】:

  • 不错的回答!但我不明白为什么我们应该使用function(events, args),为什么function(args) 不起作用,因为我们没有在函数中使用事件参数??
  • @NishanthMatha 这就是 Angular 定义它的方式。事件有其用途,只是碰巧在我提供的示例中没有用。从 event 参数我们可以确定我们在哪个作用域或 preventProgation 等。
  • 谢谢。所以$on默认可以访问event参数??如果是这样,所有其他角度内置函数都可以访问event 参数吗??
  • 是的,$on 中的侦听器函数将event 作为其第一个参数。不是所有的角度内置函数都像这样,因为 $on 正在监听一个正在被触发的事件,它有这个。
  • Sorry 可能是一个新手问题,但是如果你的两个控制器被分配到 app,js 中 .config 下的两个不同视图,在这种情况下 SecondCtrl 将不会得到任何数据,因为控制器会重新- 实例化,对吗?
【解决方案2】:

上一个答案很好。我只想补充一点:这种 $on 类型的侦听器有一个非常重要的属性:可以取消(停止)。 我会解释我的意思:

html:

<div ng-controller="FirstCtrl">
    <input ng-model="name"/> 
    <button ng-click="register()">Register </button>
</div>

<div ng-controller="SecondCtrl">
    Registered Name: <input ng-model="name"/> 
</div>
<hr/><br/>
<button ng-click="disableEvents()">Disable events</button>

还有控制器:

app.controller('SecondCtrl', function($scope){
  $scope.cancelOn = $scope.$on('BOOM!', function(events, args){
    console.log(args);
    $scope.name = args; //now we've registered!
  });

  // this will cancel the event listening....
  $scope.disableEvents = function(){
    console.log('Canceling the event listener: ', $scope.cancelOn());
  }
});

如果您按下“注册”按钮,您可以看到它与第二个控制器进行通信。现在按下“禁用事件”按钮。这将取消监听器,$on(...)。现在,如果您再次按下“注册”,您会注意到监听器不再监听此类事件。

【讨论】:

    猜你喜欢
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 2016-02-04
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    相关资源
    最近更新 更多