在isolate指令定义中使用的ngModel

时间:2014-06-03 11:10:17

标签: angularjs angularjs-directive angular-ngmodel

我的名称为datePicker的指令在输入元素上,从模型获取格里高尔日期并将其转换为最终用户的波斯日期。 从datePicker更改日期(这里是jalali(波斯日期选择器)),将nessaccery转换为gregorian并更新模型。

  1. 我不确定使用的绑定类型。
  2. $ watch函数对我不起作用,它首先加载页面时有效 时间。
  3. 隔离的ngModel和dateDirVal属性发生了什么 范围?
  4. gregorianToJalali函数中的ngModelCtrl。$ viewValue的值 等于NaN。为什么?
  5. 我的HTML:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <link href="css/jalali/theme.css" rel="stylesheet" />
        <script src="Scripts/jalali/jalali.js"></script>
        <script src="Scripts/jalali/calendar.js"></script>
        <script src="Scripts/jalali/calendar-setup.js"></script>
        <script src="Scripts/jalali/calendar-fa.js"></script>
    
        <script src="Scripts/jquery-1.7.1.min.js"></script>
        <script src="Scripts/angular.min.js"></script>
        <script src="Scripts/directive.js"></script>
    
    </head>
    <body ng-app="myApp">
        <div ng-controller="myController">
            <input ng-model="dateValue1" date id="id1" />
        </div>
    </body>
    </html>
    

    和我的指示:

    var app = angular.module('myApp', []);
    
    app.controller('myController', function ($scope) {
        var date = new Date('2014', '06', '03');
        var newdate = new Date(date);
    
        newdate.setDate(newdate.getDate() + 1);
        $scope.dateValue1 = new Date(newdate);
    })
    .directive('date', function ($compile) {
        return {
            restrict: 'A',
            require: ['date', '^ngModel'],
            scope: {
                dateDirVal: "=ngModel"
            },
            controller: function ($scope) {
    
            },
            compile: function (element, attr, linker) {
                return {
    
                    post: function postLink($scope, element, attrs, ctrls) {
                        var myCtrl = ctrls[0], ngModelCtrl = ctrls[1];
    
                        var inputId = element.attr('id').toString();
                        gregorianToJalali();
                        function gregorianToJalali() {
                            var val = ngModelCtrl.$viewValue;
                            if ($scope.dateDirVal) {
                                var inputValue = $scope.dateDirVal;
                                var gDate = new Date(inputValue);
                                var gY = gDate.getFullYear();
                                var gM = gDate.getMonth();
                                var gD = gDate.getDate();
                                var value = JalaliDate.gregorianToJalali(gY, gM, gD);
                                var jalali = value[0].toString() + "/" + value[1].toString() + "/" + value[2].toString();
                                $scope.dateDirVal = jalali;
                            }
                        }
    
                        Calendar.setup({
                            inputField: inputId,
                            ifFormat: '%Y/%m/%d',
                            dateType: 'jalali'
                        });
    
                        element.bind("blur", function (e) {
                            var jDate = element.val().split('/');
                            var value = JalaliDate.jalaliToGregorian(jDate[0], jDate[1], jDate[2]);
                            var gDate = new Date(value[0], value[1], value[2]);
                            ngModelCtrl.$setViewValue(gDate);
                            $scope.dateDirVal = value;
                        });
    
                        $scope.$watch("dateDirVal", function (newValue, OldValue, scope) {
                            if (newValue) {
                                alert(JSON.stringify(newValue));
                            }
                            //ngModelCtrl.$setViewValue(gDate);
                            //$scope.dateDirVal = value;
                        });
    
                    }
                }
            }
        };
    });
    

1 个答案:

答案 0 :(得分:1)

你可以使用$ parsers和$ formatters函数管道来做到这一点。

$ parsers 上的函数会对DOM更改做出反应,其返回会更改模型。因此,你可以使用toGregorianDate函数来转换波斯日期并保持格里高利。

$ formatters 上的函数会对模型更改做出反应,因此,只要模型发生更改(包括第一次渲染),就会触发它,并将其返回呈现到DOM中。因此,您可以使用它来调用toPersianDate函数并将gregorian转换为波斯日期以呈现给您的用户。

  

这些功能是听众,并且非常谨慎   ngModelController DOCs上记录的编译函数   提醒听众应该在链接功能上使用

所以我建议你改变一下你的代码看起来更像

.directive('date', function ($compile) {
    return {
        restrict: 'A',
        require: ['date', '^ngModel'],
        scope: {
            dateDirVal: "=ngModel"
        },
        controller: function ($scope) {

        },
        //use link instead of compiler to use DOM listeners
        link: function ($scope, element, attrs, ctrls) {
            var myCtrl = ctrls[0], ngModelCtrl = ctrls[1];

            var inputId = element.attr('id').toString();

            function gregorianToJalali(viewValue) {
                if ($scope.dateDirVal) {
                    var inputValue = $scope.dateDirVal;
                    var gDate = new Date(inputValue);
                    var gY = gDate.getFullYear();
                    var gM = gDate.getMonth();
                    var gD = gDate.getDate();
                    var value = JalaliDate.gregorianToJalali(gY, gM, gD);
                    var jalali = value[0].toString() + "/" + value[1].toString() + "/" + value[2].toString();

                    //The return of a $parsers is what is saved to the model
                    return jalali;
                }
            }

            Calendar.setup({
                inputField: inputId,
                ifFormat: '%Y/%m/%d',
                dateType: 'jalali'
            });

            function jalaliToGregorian(viewValue) {
                var jDate = viewValue.split('/');
                var value = JalaliDate.jalaliToGregorian(jDate[0], jDate[1], jDate[2]);
                var gDate = new Date(value[0], value[1], value[2]);

                //The return of a formmatter is what is rendered on the DOM
                return gDate;
            });

            //with that, jalaliToGregorian will be called every time a user fill the input
            ngModelCtrl.$parsers.unshift(jalaliToGregorian(viewValue))

            //gregorianToJalali will be called every time a model change, converting 
            // gregorian dates and presenting persian date on the view
            ngModelCtrl.$formatters.unshift(gregorianToJalali(viewValue))

        }
    };
});

我试图不改变你的代码以便弄清楚发生了什么......所以我既没有改变你的 jalaliToGregorian 函数,但是你需要注意, $ parsers 函数将绑定到模型返回...并且您没有检查输入日期是否完全是波斯日期...如果函数返回undefined,模型将不会更改...并且如果返回其他内容,该返回将被绑定,是否为日期(如果输入日期错误,则可以绑定null)

相关问题