javascript - 为什么 $watch 中的监听函数没有被触发?

标签 javascript html angularjs angularjs-directive

我有这个下拉多选指令:

JavaScript 方面:

'use strict';

var app = angular.module('myApp', ['app.directives']);

app.controller('AppCtrl', function($scope){                     
    $scope.roles = [
          {"id": 1, "name": "Manager", "assignable": true},
          {"id": 2, "name": "Developer", "assignable": true},
          {"id": 3, "name": "Reporter", "assignable": true}
    ];
    
    $scope.member = {roles: []};
    $scope.selected_items = [];
});

var app_directives = angular.module('app.directives', []);

app_directives.directive('dropdownMultiselect', function(){
   return {
       restrict: 'E',
       scope:{           
            model: '=',
            options: '=',
            pre_selected: '=preSelected'
       },
       template: "<div class='btn-group' data-ng-class='{open: open}'>"+
        "<button class='btn btn-small'>Select</button>"+
                "<button class='btn btn-small dropdown-toggle' data-ng-click='open=!open;openDropdown()'><span class='caret'></span></button>"+
                "<ul class='dropdown-menu' aria-labelledby='dropdownMenu'>" + 
                    "<li><a data-ng-click='selectAll()'><i class='icon-ok-sign'></i>  Check All</a></li>" +
                    "<li><a data-ng-click='deselectAll();'><i class='icon-remove-sign'></i>  Uncheck All</a></li>" +                    
                    "<li class='divider'></li>" +
                    "<li data-ng-repeat='option in options'> <a data-ng-click='setSelectedItem()'>{{option.name}}<span data-ng-class='isChecked(option.id)'></span></a></li>" +                                        
                "</ul>" +
            "</div>" ,
       controller: function($scope){
           var count = '1';       
               $scope.$watch(count, function() {
        alert(count)
    });
               
           $scope.openDropdown = function(){        
                    $scope.selected_items = [];
                    for(var i=0; i<$scope.pre_selected.length;i++){                        $scope.selected_items.push($scope.pre_selected[i].id);
                    }};
           
            $scope.selectAll = function () {
                $scope.model = _.pluck($scope.options, 'id');
                console.log($scope.model);
            };            
            $scope.deselectAll = function() {
                $scope.model=[];
                console.log($scope.model);
            };
            $scope.setSelectedItem = function(){
                count = count +1;
                var id = this.option.id;
                if (_.contains($scope.model, id)) {
                    $scope.model = _.without($scope.model, id);
                } else {
                    $scope.model.push(id);
                }
                console.log($scope.model);
                return false;
            };
            $scope.isChecked = function (id) {                 
                if (_.contains($scope.model, id)) {
                    return 'icon-ok pull-right';
                }
                return false;
            };                                 
       }
   } 
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="AppCtrl">    
    <dropdown-multiselect pre-selected="member.roles" model="selected_items" options="roles"></dropdown-multiselect>
    
    <pre>selected roles = {{selected_items | json}}</pre>
</div>

内部指令我有这些行:

$scope.$watch(count, function() {
    alert(count)
});

在函数 $scope.setSelectedItem 中,我有这一行 count = count+1。 当我检查下拉元素中的项目时,count 变量被修改(增加)。

我希望 $watch 当计数变量发生变化并弹出警报窗口时将被触发。

但是当我从下拉框中选择项目时,警报窗口不会弹出,而且似乎没有触发监听器。

知道我遗漏了什么吗?为什么 $watch 中的监听函数没有被触发?

最佳答案

您需要将 count 放在您的 $scope 上以使用这样的观察器。观察以下变化...

$scope.count = 1;

$scope.setSelectedItem = function() {
    $scope.count += 1;
[...]


// -- string argument
$scope.$watch('count', function(newVal, oldVal) {
    alert(newVal) // -- or $scope.count
});

JSFiddle Link - 这是一个简单的演示,展示了您的初始方法与此方法之间的区别。


尽管您可以将观察器修改为 $watch 局部变量,但声明看起来会略有不同。观察以下...

var count = 1;

$scope.setSelectedItem = function() {
    count += 1;
[...]


scope.$watch(function () {
    return count // -- return local variable
}, function(newVal, oldVal) {
    console.log(newVal)
});

JSFiddle Link - $watch 局部变量

关于javascript - 为什么 $watch 中的监听函数没有被触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32798482/

相关文章:

javascript - 使用 jQuery 和表单插件引用对表单数据 POST 的 JSON 响应

javascript - 什么是语言环境字符串?

javascript - !doctype html 毁了我的脚本

html - 在行中 float div 后填充空白

javascript - Node.js - POST 到 iFrame?

javascript - $sessionStorage 以及如何在 AngularJs 中查看和使用 $sessionStorage

javascript - 选择下一个元素轮播

javascript - 单击它时如何弹出一个 float /粘性窗口?

php - AngularJS 无法将数据插入 phpMyadmin (mySql)

javascript - AngularJS HTTP 使用响应