2

我正在为输入掩码做一个指令。但是,当我将字符串作为值传递时,属性是未定义的。如果我直接通过面具它正在工作。

.directive('inputMask', function () {
return {
    restrict: 'EAC',
    scope: true,
    link: function (scope, element, attrs) {
        scope.$watch('inputMask', function (newVal) {
            console.log('inputMask', newVal);
        });
        var maskType = scope.$eval(attrs.inputMask);
        switch (maskType) {
            case 'phone':
                $(element).inputmask("phone", {
                    url: '@Url.Content("~/Scripts/jquery-inputmask/phone-codes/phone-codes.json")',
                    onKeyValidation: function () { //show some metadata in the console
                        console.log($(this).inputmask("getmetadata")["name_en"]);
                    }
                });
                break;
            case 'money':
                $(element).inputmask("decimal", { digits: 2 });
                break;
            case 'moneyGrouped':
                $(element).inputmask("decimal", {
                    radixPoint: ",",
                    autoGroup: true,
                    groupSeparator: ".",
                    groupSize: 3,
                    digits: 2
                });
                break;
            case 'email':
                $(element).inputmask('Regex', { regex: "[a-zA-Z0-9._%-]+@[a-zA-Z0-9-]+\\.[a-zA-Z]{2,4}" });
            default:
                $(element).inputmask(maskType);
        }

        $(element).inputmask(scope.$eval(attrs.inputMask));
        $(element).on('keypress', function () {
            scope.$eval(attrs.ngModel + "='" + element.val() + "'");
        });
    }
};
});

工作(将进入默认开关):

<input type="teste" name="teste" value="" ng-model="form.email" input-mask='{ "mask": "d/m/y", "autoUnmask" : true}'/>

不工作,attrs.inputMaskundefined(应该输入以防“钱”):

<input type="teste" name="teste" value="" ng-model="form.email" input-mask='money'/>

怎么了?

4

3 回答 3

3

当您使用时,scope: true将为该指令创建一个新范围。然后,为了您的$watch工作正常,您应该为当前范围创建一个名为 inputMask 的新属性,该属性接收attrs.inputMask

scope.inputMask = attrs.inputMask;
scope.$watch('inputMask', function (newVal) {
    console.log('inputMask', newVal);
});

你可以在这里看到一个简化的工作小提琴

另一种选择是在指令的范围属性中使用哈希对象。

指令文档写道:

{}(对象哈希) - 创建一个新的“隔离”范围。“隔离”作用域与普通作用域的不同之处在于它在原型上并不从父作用域继承。这在创建可重用组件时很有用,这些组件不应意外读取或修改父范围内的数据。

(...)

@ 或 @attr - 将本地范围属性绑定到 DOM 属性的值。

这样,您可以创建绑定 DOM 属性的范围:

scope: { 
    inputMask: "@" 
},
link: function (scope, element, attrs) {
    scope.$watch('inputMask', function (newVal) {
        console.log('inputMask', newVal);
    });
    /* ... */
}

小提琴

于 2013-10-21T12:37:54.773 回答
0

在指令使用中,

范围:{inputMask:'@'}

并且在链接函数中而不是使用 attr.inputMask 使用 scope.inputMask 并且这将起作用。

如果你想使用 attr 那么你可以使用

attr.$observe('inputMask', function() {
    console.log('changed');
}

因为最初该值是未定义的。

于 2013-10-21T18:59:24.117 回答
0

这里的实际问题是 scope.$eval('money') 将返回未定义。如果它在花括号 {} 中,或者它是一个字符串,例如“money”,则该属性应该可以很好地链接到指令。

这就是你对导致问题的价值所做的事情。

var maskType = scope.$eval(attrs.inputMask);

如果要传递内插属性,例如 {{money}},则只需要使用带有 @ 或 attrs.$observe 的隔离作用域。

于 2016-10-16T01:49:08.590 回答