简体   繁体   English

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

[英]directive $watch does not trigger on change

i have the following directive: 我有以下指令:

    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();
        }
      };
    }
  };
}]);

The function to note here is the following: 这里要注意的功能如下:

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

Then i have the following html: 然后我有以下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>

Note that i am linking the ui-refresh to gap 请注意,我将ui-refresh链接到gap

Then i have the following controller: 然后我有以下控制器:

    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;
    });

}]);

I know that the gaps variable changes however the watch does not trigger ( meaning it does not call callPlugin() 我知道差距变量会更改,但是手表不会触发(这意味着它不会调用callPlugin()

Can anyone tell me what i might have done wrong? 谁能告诉我我做错了什么?

You might be missing the deep watch: 您可能会缺少深入的了解:

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

Edit : As @Eyal pointed out, the watch works with attrs , so I deleted the first section. 编辑 :正如@Eyal指出的,该手表可以使用attrs ,因此我删除了第一部分。 However, it doesn't work without the deep watch so that part might still be helpful. 但是,如果没有深入的了解,它将无法正常工作,因此该部分可能仍会有所帮助。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM