前端Angular.js专场程序员

在 AngularJS 作用域层次结构内发出和广播事件

2016-10-11  本文已影响477人  与蟒唯舞

作用域的一个很棒的特点是具有在作用域层次结构内发出和广播事件的能力。事件允许你发送通知给该作用域内不同的层次,告诉它们事件已发生。事件可以是你选择的任何东西,例如值改变或达到阀值。这在许多情况下非常有用,如让子作用域知道一个值已在父作用域中发生变化,反之亦然。

要从作用域发出一个事件,可以使用 $emit() 方法。该方法沿着父作用域层次向上发送一个事件。任何已注册该事件的祖先作用域都会收到通知。 $emit() 方法使用下面的语法:

$scope.$emit(name, [args, ...])

其中 name 是事件名称,而 args 是传递给事件处理函数的零个或多个参数。

使用 $broadcast() 方法把一个事件广播给下方的子作用域层次。任何已注册该事件的后代作用域都会收到通知。$broadcast() 方法使用下面的语法:

$scope.$broadcast(name, [args, ...])

其中 name 是事件名称,而 args 是传递给事件处理函数的零个或多个参数。

要处理发出或广播的事件,可以使用 $on() 方法。$on() 方法使用下面的语法:

$scope.$on(name, listener)

其中 name 是要监听的事件名称,listener 是一个函数,它可以接受事件(event)作为第一个参数,并把由 $emit() 方法或 $broadcast() 方法传递的任何参数作为后续的参数。event 对象具有以下属性:

环境版本:

一个简单的页面(events.html):

<!DOCTYPE html>
<html ng-app="myApp">

<head>
    <title>AngularJS Scope Events</title>
    <style type="text/css">
    div {
        padding: 5px;
        font: 18px bold;
    }
    
    span {
        padding: 3px;
        margin: 12px;
        border: 5px ridge;
        cursor: pointer;
    }
    
    label {
        padding: 2px;
        margin: 5px;
        font: 15px bold;
    }
    
    p {
        padding-left: 22px;
        margin: 5px;
    }
    </style>
</head>

<body>
    <div ng-controller="firstCtrl">
        <span ng-repeat="name in names" ng-click="changeName()">
            {{name}}
        </span>
        <div ng-controller="secondCtrl">
            <hr>
            <label>Name:</label>
            <p>{{currentName}}</p>
            <label>Race:</label>
            <p>{{currentInfo.race}}</p>
            <label>Weapon:</label>
            <p>{{currentInfo.weapon}}</p>
            <span ng-click="del()">Delete</span>
        </div>
    </div>
    <script type="text/javascript" src="lib/angular.js"></script>
    <script type="text/javascript" src="events.js"></script>
</body>

</html>

事件处理(events.js):

(function() {
    angular.module('myApp', [])
        .controller('firstCtrl', ['$scope', function($scope) {
            $scope.names = ['Frodo', 'Aragorn', 'Legolas', 'Gimli'];
            $scope.currentName = $scope.names[0];

            $scope.changeName = function() {
                // 使用 this 关键字来访问 name 属性
                // name 属性实际上来自于被创建的一个动态子作用域
                $scope.currentName = this.name;
                $scope.$broadcast('change', this.name);
            };

            $scope.$on('delete', function(event, name) {
                var i = $scope.names.indexOf(name);
                $scope.names.splice(i, 1);
                $scope.currentName = $scope.names[0];
                $scope.$broadcast('change', $scope.currentName);

            });
        }])
        .controller('secondCtrl', ['$scope', function($scope) {
            $scope.info = {
                'Frodo': { weapon: 'String', race: 'Hobbit' },
                'Aragorn': { weapon: 'Sword', race: 'Man' },
                'Legolas': { weapon: 'Bow', race: 'Elf' },
                'Gimli': { weapon: 'Axe', race: 'Dwarf' }
            };
            $scope.currentInfo = $scope.info['Frodo'];

            $scope.$on('change', function(event, name) {
                $scope.currentInfo = $scope.info[name];
            });

            $scope.del = function() {
                delete $scope.info[$scope.currentName];
                $scope.$emit('delete', $scope.currentName);
            };
        }]);
})();

对上面代码中 this.name 的解释:

动态子作用域
上一篇 下一篇

猜你喜欢

热点阅读