【问题标题】:Angular datepicker directive with function binding带有函数绑定的 Angular 日期选择器指令
【发布时间】:2017-02-13 17:25:42
【问题描述】:

我是角度的初学者。 请帮我修复this plunk

我试图只对我的控制器中的 jquery UI datepicker 小部件的 onSelect 回调使用一个回调,而不是在每个指令中重复回调函数(是的,为了实验,我确实有多个指令)。

但是我得到了这个错误

未捕获的 TypeError:无法使用 'in' 运算符在 19/10/2016 中搜索 'onSelect'

这是我的代码

HTML

<html ng-app="myApp">
    <head>
        <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css"/>
        <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
        <script src="script.js"></script>
    </head>
    <body ng-controller="myController">
        <input type="text" my-datepicker ng-model="date" date="date" on-select="onSelect()"/>
        <input type="button" ng-click="submitDate()" value="Submit"/>
    </body>
</html>

JS

var app = angular.module('myApp', []);
app.controller('myController', ['$scope', function($scope){
    $scope.date = "frommyController";
    $scope.submitDate = function(){
        console.log($scope.date);
    };
    $scope.onSelect = function(value, picker){
        scope.date = value;
        scope.$parent.$digest();
    }
}]);
app.directive('myDatepicker', function(){
    return {
        scope: {
            date: "=",
            onSubmit: "&onSelect"
        },
        restrict: 'EA',
        require: "ngModel",
        link: function(scope, element, attributes, modelController){
            scope.date = "fromdirevtive";
            element.datepicker({
                changeMonth: true,
                changeYear: true,
                dateFormat: "dd/mm/yy",
                onSelect: scope.onSubmit
            });
        }
    }
})

谁能帮我理解我在这里做错了什么?

【问题讨论】:

  • 别忘了欣赏我的作品。
  • @chiragpatel 感谢您的帮助 chirag。我明白,因为这个回调应该是从外部环境而不是角度调用的。这是无法实现的。

标签: javascript angularjs angularjs-directive jquery-ui-datepicker


【解决方案1】:

我使用您的 plunkr 创建了一个新的 plunkr。请参阅此plunker 以获得解决方案。

在您的 plunkr 中发现的问题:

  1. index.html 中的方法签名不正确。
  2. 在 Angular 指令中使用 & 绑定调用回调的方式。

我刚刚更正了上述问题。另外,我没有使用链接功能,而是使用了指令控制器,因为它在与指令的交互方面给了我更多的控制权。

在 Angular 指令中调用回调的正确方法是传递一个对象作为参数。对象的键应该是回调函数的参数。参考app.js的第27行

代码 - app.js

var app = angular.module('myApp', []);
app.controller('myController', ['$scope',
  function($scope) {
    $scope.date = "frommyController";
    $scope.submitDate = function() {
      console.log($scope.date);
    };
    $scope.onSelect = function(value, picker) {
      console.log(value);
      console.log(picker);
      $scope.date = value;
      $scope.$parent.$digest();

    }
  }
]);
app.directive('myDatepicker', function() {
  return {
    scope: {
      date: "<",
      onSelect: "&"
    },
    restrict: 'EA',
    require: "ngModel",
    controller: function($scope, $element) {
      vm = this;
      vm.$scope = $scope;
      vm.onSelect = function(value, picker) {
        vm.$scope.onSelect({
          value: value,
          picker: picker
        })
      }

      $element.datepicker({
        changeMonth: true,
        changeYear: true,
        dateFormat: "dd/mm/yy",
        onSelect: vm.onSelect
      });

    }
  }
})


<html ng-app="myApp">

<head>
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" />
  <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="myController">
  <input type="text" my-datepicker ng-model="date" date="date" on-select="onSelect(value,picker)" />
  <input type="button" ng-click="submitDate()" value="Submit" />
</body>

</html>

【讨论】:

    【解决方案2】:

    你有两个选择

    选项 1:

    在指令中调用你的回调函数,如下所示:

    var app = angular.module('myApp', []);
    app.controller('myController', ['$scope', function($scope){
        $scope.date = "frommyController";
        $scope.submitDate = function(){
            console.log($scope.date);
        };
        $scope.onSelect = function(value, picker){
          alert('');
            scope.date = value;
            scope.$parent.$digest();
        }
    }]);
    app.directive('myDatepicker', function(){
        return {
            scope: {
                date: "=",
                onSubmit: "&onSelect"
            },
            restrict: 'EA',
            require: "ngModel",
            link: function(scope, element, attributes, modelController){
                scope.date = "fromdirevtive";
                element.datepicker({
                    changeMonth: true,
                    changeYear: true,
                    dateFormat: "dd/mm/yy",
                    onSelect: function(){scope.$apply(function() {
                        scope.onSubmit();
                    }); }
                });
            }
        }
    })
    

    选项 2:

    使用发布者/订阅者模型在你的父控制器中做一些事情......如下所示

    var app = angular.module('myApp', []);
    app.controller('myController', ['$scope', function($scope){
        $scope.date = "frommyController";
        $scope.submitDate = function(){
            console.log($scope.date);
        };
    
        $scope.$on('event',function()
        {
          alert('listener');
            scope.date = value;
            scope.$parent.$digest();
        });
    
    }]);
    app.directive('myDatepicker', function(){
        return {
            scope: {
                date: "="
            },
            restrict: 'EA',
            require: "ngModel",
            link: function(scope, element, attributes, modelController){
                scope.date = "fromdirevtive";
                element.datepicker({
                    changeMonth: true,
                    changeYear: true,
                    dateFormat: "dd/mm/yy",
                    onSelect: function(){scope.$apply(function() {
                      console.log(scope)
                        scope.$emit('event')
                    });}
                });
            }
        }
    })
    

    【讨论】:

      【解决方案3】:

      试试下面的目录,而不是你的目录:

      app.directive('myDatepicker', function(){
          return {
              scope: {
                  date: "=",
                  onSubmit: "&onSelect"
              },
              restrict: 'EA',
              require: "ngModel",
              link: function(scope, element, attributes, modelController){
                  scope.date = "fromdirevtive";
                  element.datepicker({
                      changeMonth: true,
                      changeYear: true,
                      dateFormat: "dd/mm/yy",
                      onSelect:function(date) {
      
                      scope.$apply(function() {
                          modelController.$setViewValue(date); 
                      }); 
                  }
                  });
              }
          }
      })
      

      希望这对你有帮助。

      【讨论】:

      • 这就是我想避免在多个指令中创建多个回调。
      • @nikhilmehta ,检查更新的答案,现在这对你有用。我也在你的 plunker 中尝试了这个并且它正在工作,你可以检查在你的 plunker 中替换此代码
      • 那么将 onSubmit 传递给指令范围是没有用的
      • @nikhilmehta,如果对你有帮助,别忘了欣赏我的作品
      • 你是对的,这些是我可以实现目标的方法。但我正在学习角度,并希望通过参考在多个日期选择器指令中仅使用一个回调 onSelect。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2014-07-25
      相关资源
      最近更新 更多