Javascript 如何将数据从指令模板传递到控制器?

Javascript 如何将数据从指令模板传递到控制器?,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我正在建造一种日期选择器,实际上是两个日期选择器。 一个用于开始日期,另一个用于结束日期。每个datepicker元素生成一个包含2个输入标记()的模板。我想将数据从输入的value属性传递到控制器。 我试图在内部范围中定义双向数据绑定(dateOne和dateTwo)的字段,但显然没有效果,也没有实际数据在这两个字段之间传递。 我的另一种方法是使用ng模型,但我对这个特性没有什么经验,也不知道它的规则。 这是我的密码 angular.module('directives', []) .

我正在建造一种日期选择器,实际上是两个日期选择器。 一个用于开始日期,另一个用于结束日期。每个datepicker元素生成一个包含2个输入标记()的模板。我想将数据从输入的value属性传递到控制器。 我试图在内部范围中定义双向数据绑定(dateOne和dateTwo)的字段,但显然没有效果,也没有实际数据在这两个字段之间传递。 我的另一种方法是使用ng模型,但我对这个特性没有什么经验,也不知道它的规则。 这是我的密码

angular.module('directives', [])
    .directive('datepicker', ['$timeout',function ($timeout) {
        // Runs during compile
        return {
            scope: {
                id: '@',
                "class": '@',
                dateOne: '=',
                dateTwo: '='
            },
                restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
                template: '<div id="{{id}}" class="{{class}}">'+
                        '<div class="date-wrapper">'+
                            '<label for="datepicker-start">From:</label>'+
                            '<div class="fieldWrapper">'+
                                '<input id="datepicker-start" type="date" placeholder="Select date" value={{dateOne}} />'+
                                '<a class="calendar"></a>'+
                            '</div>'+
                        '</div>'+
                        '<div class="date-wrapper">' +
                            '<label for="datepicker-end">To:</label>' +
                            '<div class="fieldWrapper">' +
                                '<input id="datepicker-end" type="date" placeholder="Select date" value={{dateTwo}}/>' +
                                '<a class="calendar"></a>' +
                            '</div>' +
                        '</div>'+
                        '</div>'
                        ,
                replace: true,
            link: function($scope, iElm, iAttrs, controller) {
                console.log('directive link function');
                console.log('directive iAttrs', iAttrs);
                $(".date-wrapper").each(function (index) {
                    console.log('directive index', index);
                    $input = $(this).find('input');
                    $btn = $(this).find('.calendar');

                    console.log('input', $input[0]);
                    console.log('btn', $btn[0]);

                    $input.attr('type', 'text');
                    var pickerStart = new Pikaday({
                        field: $input[0],
                        trigger: $btn[0],
                        container: $(this)[0],
                        format: 'DD/MM/YYYY',
                        firstDay: 1
                    });
                    $btn.show();
                });

            }
        };
}]);
角度模块('指令',[]) .directive('datepicker',['$timeout',function($timeout){ //在编译期间运行 返回{ 范围:{ id:“@”, “类”:“@”, dateOne:“=”, 日期二:'=' }, 限制:'E',//E=Element,A=Attribute,C=Class,M=Comment 模板:“”+ ''+ “发件人:”+ ''+ ''+ ''+ ''+ ''+ '' + “致:”+ '' + '' + '' + '' + ''+ '' , 替换:正确, 链接:功能($scope、iElm、iAttrs、controller){ console.log('directive link function'); console.log('指令iAttrs',iAttrs); $(“.date包装器”)。每个(函数(索引){ log('指令索引',索引); $input=$(this.find('input'); $btn=$(this.find('.calendar'); log('input',$input[0]); console.log('btn',$btn[0]); $input.attr('type','text'); var pickerStart=新的皮卡日({ 字段:$input[0], 触发器:$btn[0], 容器:$(此)[0], 格式:“DD/MM/YYYY”, 第一天:1 }); $btn.show(); }); } }; }]); ------------------------更新代码-----------------------------------

angular.module('directives', [])
    .directive('datepicker', ['$timeout',function ($timeout) {
        // Runs during compile
        return {
            scope: {
                id: '@',
                "class": '@',
                dateOne: '=',
                dateTwo: '='
            },
                restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
                template: '<div id="{{id}}" class="{{class}}">'+
                        '<div class="date-wrapper">'+
                            '<label for="datepicker-start">From:</label>'+
                            '<div class="fieldWrapper">'+
                                '<input id="datepicker-start" type="date"  placeholder="Select date" ng-model=dateOne />' +
                                '<a class="calendar"></a>'+
                            '</div>'+
                        '</div>'+
                        '<div class="date-wrapper">' +
                            '<label for="datepicker-end">To:</label>' +
                            '<div class="fieldWrapper">' +
                                '<input id="datepicker-end" type="date" placeholder="Select date" ng-model=dateTwo />' +
                                '<a class="calendar"></a>' +
                            '</div>' +
                        '</div>'+
                        '</div>'
                        ,
                replace: true,
            link: function($scope, iElm, iAttrs, controller) {
                console.log('directive iAttrs', iAttrs);
                $(".date-wrapper").each(function (index) {
                    console.log('directive index', index);
                    $input = $(this).find('input');
                    $btn = $(this).find('.calendar');

                    console.log('input', $input[0]);
                    console.log('btn', $btn[0]);

                    $input.attr('type', 'text');
                    var pickerStart = new Pikaday({
                        field: $input[0],
                        trigger: $btn[0],
                        container: $(this)[0],
                        format: 'DD/MM/YYYY',
                        firstDay: 1
                    });
                    $btn.show();
                });

                $scope.$watch(iAttrs.dateOne, function (newValue, oldValue) {
                    console.log('newValue', newValue);
                    console.log('oldValue', oldValue);
                }, true);

            }
        };
角度模块('指令',[]) .directive('datepicker',['$timeout',function($timeout){ //在编译期间运行 返回{ 范围:{ id:“@”, “类”:“@”, dateOne:“=”, 日期二:'=' }, 限制:'E',//E=Element,A=Attribute,C=Class,M=Comment 模板:“”+ ''+ “发件人:”+ ''+ '' + ''+ ''+ ''+ '' + “致:”+ '' + '' + '' + '' + ''+ '' , 替换:正确, 链接:功能($scope、iElm、iAttrs、controller){ console.log('指令iAttrs',iAttrs); $(“.date包装器”)。每个(函数(索引){ log('指令索引',索引); $input=$(this.find('input'); $btn=$(this.find('.calendar'); log('input',$input[0]); console.log('btn',$btn[0]); $input.attr('type','text'); var pickerStart=新的皮卡日({ 字段:$input[0], 触发器:$btn[0], 容器:$(此)[0], 格式:“DD/MM/YYYY”, 第一天:1 }); $btn.show(); }); $scope.$watch(iAttrs.dateOne,函数(newValue,oldValue){ console.log('newValue',newValue); console.log('oldValue',oldValue); },对); } };
  • 将模板中的值替换为ng model=dateOne,将其替换为dateTwo

  • 我建议为这个指令使用一个专用的控制器,不要在link函数中执行逻辑

  • app.directive('someDirective',function(){ 返回{ 限制:“A”, 控制器:“SomeController”, controllerAs:'ctrl', 模板:“{ctrl.foo}” }; }))


    在这里阅读更多内容

    事实上,你已经差不多做到了,我做了一些与你描述的非常相似的事情,这里是我解决问题的方法(我在我的案例中使用了UI引导日期选择器)

    从指令向控制器发送数据的方式是使用回调,而不是简单的监视。如果要使用
    =
    ,则必须在控制器(和指令)中设置监视以监视值更改,这是一种不好的做法

    所以基本上你需要做的是

  • 在指令定义中,对象使用
    &
    符号绑定回调方法/函数,如下所示

    scope: {
        onSelect: "&" // onSelect is our callback function in the ctrl
    }
    
  • 然后,为回调属性提供一个绑定到控制器$scope的函数,但向它传递一个函数引用(而不是像ng changed那样的函数调用)

  • 然后定义所选的
    应该是什么
    
    // inside controller
    $scope.onSelected = function(time) {
        console.log("Time selected: ", time);
    }
    
    scope.selectDate = function(time) {
        if (angular.isFunction(scope.onSelect())) {
            // we use isFunction to test if the callback function actually
            // points to a valid function object
            scope.onSelect()(time); // we pass out new selected date time
          }
      }