如何保持显示值和内部值同步

How to keeps the display value and internal value synchronized

我想知道使显示字符串值与指令的实际内部值保持一致的最佳方法是什么。

在下面的代码中,我有一个时间输入,用户可以在其中输入表示时间的字符串(“00:00”),每次用户更改字符串值时,指令都会计算实际值并相应地设置它.

但是,由于实际值是暴露的并且可以被其他组件更改,我需要一些方法使字符串值与实际值一致。

$watch 是一种解决方案,但我需要在 onChange() 方法中禁用手表。所以,我想知道是否有更好的方法来做到这一点。

[编辑]:我使用 ng-blur 的原因是在字符串值不是有效格式的情况下进行验证,它会恢复为实际值。

干杯,

Jsfiddle:https://jsfiddle.net/minhnq013/v5rax0vk/3/

angular.module('myapp', [])
    .directive('timeInput', function () {
    return {
        restrict: 'E',
        template: '<input type="text" ng-model="ctrl.strValue" ng-blur="ctrl.onChange()"/><span ng-bind="ctrl.value"></span>',
        scope: {
            'value': '='
        },
        controller: Controller,
        controllerAs: 'ctrl',
        bindToController: true
    };

    function Controller() {
        var ctrl = this;
        ctrl.value = ctrl.value || 0;
        ctrl.strValue = "00:00";

        /**
         *  Called when the UI determine user input value has change,
         *  Set the internal value to be same as user input text value.
         **/
        function onChange() {
            var hour = ctrl.strValue.substr(0, 2);
            var minute = ctrl.strValue.substr(3);
            var dateObj = new Date(ctrl.value);
            var regex = new RegExp("^\d{2}:\d{2}$");
            // If format is not valid, revert to last value
            if (!ctrl.strValue.match(regex)) {
                ctrl.strValue = ("0"+dateObj.getUTCHours()).slice(-2) + ":" + ("0"+dateObj.getUTCMinutes()).slice(-2);
                return;
            }

            dateObj.setUTCHours(hour);
            dateObj.setUTCMinutes(minute);
            ctrl.value = dateObj.getTime();
        }
        ctrl.onChange = onChange;

        function filterText() {

        }
    }
});

我会使用过滤器。如果您在多个位置使用此代码,则可以使用使用过滤器的指令。

过滤器将负责显示格式化的内部数据。这将消除为一个值存储两个对象的需要。

此外,使用过滤器将消除 onChange 事件的需要。

有关过滤器的更多信息,请参阅:https://scotch.io/tutorials/building-custom-angularjs-filters

有很多不同的方法来构建它,但我建议您不要使用手表,而要尝试让它保持事件驱动。我部分地基于你的代码评论而不是你的问题 Called when the UI determine user input value has change,但听起来你可能只是在考虑你想要实现的错误事件。将 ng-blur 更改为 ng-change 之类的东西怎么样,以便您的函数在每次更改时运行以保持您的逻辑同步。您可以轻松地将其与模型选项配对以获得一些非常棒的功能,例如,如果您希望将其减慢到半秒更新,如下所示: ng-model-options="{ debounce: { 'default': 500 } }"

template: '<input type="text" ng-model="ctrl.strValue" ng-change="ctrl.onChange()"/><span ng-bind="ctrl.value"></span>',

四处寻找后,我发现这个 post 似乎是解决问题的正确方法。

创建一个新的指令限制属性并作为文本输入值的过滤器。