指令链接中的范围变量不会更新到指令控制器使用 Angular 读取它时

Scope variable in Directive Link is not updated to when Directive Controller reads it using Angular

本文关键字:指令控制器 Angular 读取 更新 链接 范围 变量 指令      更新时间:2023-09-26

这是我的代码

    var directive = {
        restrict: 'E',
        templateUrl: '/static/myTemplate.html',
        scope: {
        },
        controller: ["$scope", controllerFunc],
        controllerAs: 'multiCheckboxCtrl',
        bindToController: true,
        link: linkFunc,
    };
    return directive;

    function controllerFunc($scope) {
        // $watch List
        /**
         * Event handler for searchText change
         */
        $scope.$watch(angular.bind(this, function () {
            return $scope.multiCheckboxCtrl.clickedElsewhere.value;
        }), function (newVal) {
            if (newVal !== undefined && newVal !== "") {
                console.log(newVal);
                console.log("I am here");
            }
        });

    }
    function linkFunc(scope, element, attr){
        // Detect Element Click Logic
        scope.multiCheckboxCtrl.clickedElsewhere = {value: false};
        $document.on('click', function(){
            scope.multiCheckboxCtrl.clickedElsewhere.value = false;
            console.log(scope.multiCheckboxCtrl.clickedElsewhere);
        });
        element.on('click', function(){
            event.stopPropagation();
            scope.multiCheckboxCtrl.clickedElsewhere.value = true;
            console.log(scope.multiCheckboxCtrl.clickedElsewhere);
        });
        // End Detect Element Click Logic
    }

linkFunc 基本上确定是否单击指令元素。

我验证了每当单击指令元素时,它都会控制台 true,而当单击指令元素之外的任何元素时,它都会控制台 false。

但是,似乎我在控制器中的$watch没有捕捉到变化。

谁能告诉我出了什么问题

谢谢

Angular 不知道事件侦听器中存在更改对象属性。

正如文档所说:

$apply()用于从角度框架外部执行角度表达式。(例如,从浏览器DOM eventssetTimeoutXHR或第三方库)。因为我们正在调用角度框架,所以我们需要执行异常处理的适当范围生命周期,执行监视。

jsfiddle上的活生生的例子。

angular.module('ExampleApp', [])
  .controller('ExampleController', function($scope) {
   
  })
  .directive('clickDirective', function() {
    var directive = {
      restrict: 'E',
      template: '<div>click me</div>',
      scope: {},
      controller: ["$scope", controllerFunc],
      controllerAs: 'multiCheckboxCtrl',
      bindToController: true,
      link: linkFunc,
    };
    return directive;
    function controllerFunc($scope) {
      // $watch List
      /**
       * Event handler for searchText change
       */
      $scope.$watch(function() {
        return $scope.multiCheckboxCtrl.clickedElsewhere.value;
      }, function(newVal) {
        if (newVal !== undefined && newVal !== "") {
          console.log(newVal);
          console.log("I am here");
        }
      });
    }
    function linkFunc(scope, element, attr) {
      // Detect Element Click Logic
      scope.multiCheckboxCtrl.clickedElsewhere = {
        value: false
      };
      angular.element(document).on('click', function() {
        scope.multiCheckboxCtrl.clickedElsewhere.value = false;
        console.log(scope.multiCheckboxCtrl.clickedElsewhere);
        scope.$apply();
      });
      element.on('click', function() {
        event.stopPropagation();
        scope.multiCheckboxCtrl.clickedElsewhere.value = true;
        console.log(scope.multiCheckboxCtrl.clickedElsewhere);
        scope.$apply();
      });
      // End Detect Element Click Logic
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="ExampleApp">
  <div ng-controller="ExampleController" id="ExampleController">
    <click-directive></click-directive>
    <div>
       click elsewhere
    </div>
  </div>
</div>