【问题标题】:Angularjs $watch() not changing valuesAngularjs $watch() 不改变值
【发布时间】:2015-07-12 22:58:43
【问题描述】:

我已经为自定义指令的属性添加了$watch()(它又是范围变量)。当作用域变量的值改变时,指令的相应属性值不会改变,因此值函数不会被触发。

这里是html代码:

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

<head>
    <script src="js/angular.min.js"></script>
    <!-- some code -->
</head>

<body>

    <div ng-controller=visCtrl class="container col-sm-12">

        <div timeline-chart vis-file=skillFile class="divVis divVisLine col-sm-12">
            <!-- some code -->
        </div>

        <div skill-chart vis-file=skillFile exp-key={{selectedDataKey}} class="divVis divVisLine col-sm-12">
            <!-- some code -->
        </div>


    </div>

    <!-- some code -->
</body>

</html>

这里是JS代码:

var myApp = angular.module('myApp', ['ui.utils']);

myApp.controller('visCtrl', function($scope) {

    $scope.selectedDataKey = 4;

});


myApp.directive('timelineChart', function($window) {
            return {
                restrict: 'EA',
                link: function(scope, elem, attrs) {



                    drawTimeLine = function() {
                        var chart = d3.timeline()
                            //some code
                            .click(function(d, i, datum) {
                                //console.log(scope);
                                console.log("previously selectedDataKey was:" + scope.selectedDataKey);
                                scope.selectedDataKey = datum.key;
                                console.log("selectedDataKey changed to:" + scope.selectedDataKey);
                            });

                        d3.csv(dataFile, function(error, data) {
                                //some code
                            }

                            drawTimeLine();
                        }
                    }
                });

            myApp.directive('skillChart', function($window) {
                return {
                    restrict: 'EA',
                    /*template:"<svg width='850' height='200'></svg>",*/
                    link: function(scope, elem, attrs) {
                        var dataKey = attrs.expKey || false;

                        scope.$watch(function() {
                            return attrs.expKey;
                        }, function(value, oldval) {
                            dataKey = value || false;
                            console.log("skillChart dataKey changed to:" + dataKey);
                            if (dataKey) {
                                drawSkillChart();
                            }
                        });

                        drawSkillChart = function() {
                            //some code
                        }

                        drawSkillChart();

                    }
                }
            });

【问题讨论】:

  • 您的问题中是否也缺少 watchexpression ?文档定义了 watch here 您希望收到通知的变量/模型。

标签: javascript angularjs


【解决方案1】:

要查看指令属性的变化,您需要使用$observe 而不是$watch。所以改变你的代码是这样的:

 link: function(scope, elem, attrs) {
      var dataKey = attrs.expKey || false;

      attrs.$observe('expKey', function() {
            // your code on value change
      });
 }

https://docs.angularjs.org/api/ng/type/$compile.directive.Attributes

【讨论】:

    【解决方案2】:

    我尝试了一个类似的示例,它似乎可以正常工作。如果你在文本框中改变键的值,它就是在控制台打印相应指令属性的值。

    app.js

    var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($scope) {
      $scope.name = 'World';
      $scope.selectedKey = 5;
    })
    app.directive('example', function(){
      return {
        restrict: 'EA',
        link: function(scope, element, attr) {
          scope.$watch(function(){
            return attr.expKey;
          }, function(newVal, oldVal){
            if(newVal) {
              printDataKey(newVal);
            }
          });
    
          var printDataKey = function(dataKey) {
            console.log("newVal is " + dataKey);
          };
        }
      }
    });
    

    index.html

    <!DOCTYPE html>
    <html ng-app="plunker">
    
      <head>
        <meta charset="utf-8" />
        <title>AngularJS Plunker</title>
        <script>document.write('<base href="' + document.location + '" />');</script>
        <link rel="stylesheet" href="style.css" />
        <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script>
        <script src="app.js"></script>
      </head>
    
      <body ng-controller="MainCtrl">
        <input type='text' ng-model='selectedKey'>
        <p example exp-key={{selectedKey}}>Hello {{name}}!</p>
      </body>
    
    </html>
    

    这里是plnkr

    【讨论】:

      【解决方案3】:

      在您的技能图表指令中,将范围更改为 $scope,该指令如下所示:

      myApp.directive('skillChart', function($window) {
                      return {
                          restrict: 'EA',
                          /*template:"<svg width='850' height='200'></svg>",*/
                          link: function($scope, elem, attrs) {
                              var dataKey = attrs.expKey || false;
      
                              $scope.$watch(function() {
                                  return attrs.expKey;
                              }, function(value, oldval) {
                                  dataKey = value || false;
                                  console.log("skillChart dataKey changed to:" + dataKey);
                                  if (dataKey) {
                                      drawSkillChart();
                                  }
                              });
      
                              drawSkillChart = function() {
                                  //some code
                              }
      
                              drawSkillChart();
      
                          }
                      }
                  });
      

      【讨论】:

        【解决方案4】:

        检查您的范围。您可能会在 2 个不同的范围内找到变量名称“selectedDataKey”。

        改为使用对象和嵌套属性: visCtrl:

        $scope.data = {
          selectedDataKey : 4
        }
        

        时间线图:

        scope.data.selectedDataKey = datum.key;
        

        html:

        【讨论】:

          猜你喜欢
          • 2016-03-10
          • 1970-01-01
          • 2013-03-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-31
          • 1970-01-01
          相关资源
          最近更新 更多