gpt4 book ai didi

angularjs - ngModel 用于隔离指令定义

转载 作者:行者123 更新时间:2023-12-04 21:41:58 26 4
gpt4 key购买 nike

我的名为 datePicker 的指令位于输入元素上,它从模型中获取公历日期并将其转换为最终用户的波斯日期。
从 datePicker 更改日期(这里是 jalali(波斯日期选择器)),转换为 gregorian 并更新模型是必要的。

  • 我不确定我使用的绑定(bind)类型。
  • $watch 功能对我不起作用,它在第一次加载页面时起作用
    时间。
  • ngModel 和 dateDirVal 属性在隔离中发生了什么
    范围?
  • gregorianToJalali 函数中 ngModelCtrl.$viewValue 的值
    等于 NaN。为什么?

  • 我的 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;
    });

    }
    }
    }
    };
    });

    最佳答案

    您可以使用 $parsers 和 $formatters 函数管道来执行此操作。

    上的功能$解析器对 DOM 变化使用react,它的返回会改变模型。因此,您可以使用 toGregorianDate 函数来转换波斯日期并保留公历。

    上的功能$格式化程序对模型更改使用react,因此,每当模型更改(包括第一次渲染)时,它都会被触发并将其返回渲染到 DOM 中。因此,您可以使用它来调用 toPersianDate 函数并将公历转换为波斯日期以呈现给您的用户。

    These functions are listeners, and there are a big caution on compile functions documented on ngModelController DOCs alerting that listenners are supposed to be used on link functions



    所以我建议你改变一下你的代码看起来更像这样
    .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 函数将绑定(bind)到模型它的返回......而你根本不检查输入的日期是否是波斯日期...如果函数返回未定义,则模型将不会更改...如果返回其他内容,则该返回将被绑定(bind),无论是否为日期(null如果输入日期错误可以绑定(bind))

    关于angularjs - ngModel 用于隔离指令定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24013660/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com