指令$watch不会在更改时触发

directive $watch does not trigger on change

本文关键字:watch 指令      更新时间:2023-09-26

我有以下指令:

    angular.module('ui.jq', ['ui.load']).
  value('uiJqConfig', {}).
  directive('uiJq', ['uiJqConfig', 'JQ_CONFIG', 'uiLoad', '$timeout', function uiJqInjectingFunction(uiJqConfig, JQ_CONFIG, uiLoad, $timeout) {
  return {
    restrict: 'A',
    compile: function uiJqCompilingFunction(tElm, tAttrs) {
      if (!angular.isFunction(tElm[tAttrs.uiJq]) && !JQ_CONFIG[tAttrs.uiJq]) {
        throw new Error('ui-jq: The "' + tAttrs.uiJq + '" function does not exist');
      }
      var options = uiJqConfig && uiJqConfig[tAttrs.uiJq];
      return function uiJqLinkingFunction(scope, elm, attrs) {
        function getOptions(){
          var linkOptions = [];
          // If ui-options are passed, merge (or override) them onto global defaults and pass to the jQuery method
          if (attrs.uiOptions) {
            linkOptions = scope.$eval('[' + attrs.uiOptions + ']');
            if (angular.isObject(options) && angular.isObject(linkOptions[0])) {
              linkOptions[0] = angular.extend({}, options, linkOptions[0]);
            }
          } else if (options) {
            linkOptions = [options];
          }
          return linkOptions;
        }
        // If change compatibility is enabled, the form input's "change" event will trigger an "input" event
        if (attrs.ngModel && elm.is('select,input,textarea')) {
          elm.bind('change', function() {
            elm.trigger('input');
          });
        }
        // Call jQuery method and pass relevant options
        function callPlugin() {
          $timeout(function() {
            elm[attrs.uiJq].apply(elm, getOptions());
          }, 0, false);
        }
        function refresh(){
          // If ui-refresh is used, re-fire the the method upon every change
          if (attrs.uiRefresh) {
            scope.$watch(attrs.uiRefresh, function() {
              callPlugin();
            });
          }
        }
        if ( JQ_CONFIG[attrs.uiJq] ) {
          uiLoad.load(JQ_CONFIG[attrs.uiJq]).then(function() {
            callPlugin();
            refresh();
          }).catch(function() {
          });
        } else {
          callPlugin();
          refresh();
        }
      };
    }
  };
}]);

这里需要注意的功能如下:

        function refresh(){
      // If ui-refresh is used, re-fire the the method upon every change
      if (attrs.uiRefresh) {
        scope.$watch(attrs.uiRefresh, function() {
          callPlugin();
        });
      }
    }

然后我有以下html:

  <div ui-jq="plot" ui-refresh="gaps"  ui-options="
  [
    { data: {{gaps}}, label: 'Forventet', points: { show: true, fill:true } },
    { data: {{avg}}, label: 'Gns niveau', points: { show: true, fill:true } }
  ],
  {
    colors: [ '{{app.color.info}}','{{app.color.success}}' ],
    series: { shadowSize: 2, points: {radius: 8, fill: true} },
    xaxis:{ font: { color: '#ccc' } },
    yaxis:{ font: { color: '#ccc' } },
    grid: { hoverable: true, clickable: true, borderWidth: 0, color: '#ccc' },
    tooltip: true,
    tooltipOpts: { content: '%s of %x.1 is %y.4',  defaultTheme: false, shifts: { x: 0, y: 20 } }
  }
" style="height:240px"></div>

注意,我正在将ui刷新链接到gap

然后我有以下控制器:

    app.controller('CompetenceController', ['$http', '$scope', '$sessionStorage', 'competenceStatService', '$log', 'Session', 'api', function ($http, $scope, $sessionStorage, competenceStatService, $log, Session, api) {
    $scope.renderer = 'line';
    $scope.sightingsByDate = [[0, 40], [1, 49], [2, 38], [30, 4], [5, 32]];
    $scope.gaps = [];
    competenceStatService.getGaps().then(function (response) {
        $scope.gaps = response;
    });
    $scope.avg = [];
    competenceStatService.getAvg().then(function (response) {
        $scope.avg = response;
    });
}]);

我知道间隙变量会发生变化,但手表不会触发(这意味着它不会调用callPlugin()

有人能告诉我我可能做错了什么吗?

您可能错过了深度监视:

scope.$watch(attrs.uiRefresh, function() {
    callPlugin();
}, true); //added True for deep watch

编辑:正如@Eyal所指出的,这款手表适用于attrs,所以我删除了第一部分。然而,如果没有深度手表,它就无法工作,因此该部分可能仍然有帮助。

更新的小提琴:http://jsfiddle.net/fu73pz6t/3/