Javascript 模式绑定不起作用
我想使用基于select选择的ngPattern验证输入。它在第一次选择之后工作,但任何后续选择都不能正确绑定 这里有一个JSFIDLE供参考:Javascript 模式绑定不起作用,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我想使用基于select选择的ngPattern验证输入。它在第一次选择之后工作,但任何后续选择都不能正确绑定 这里有一个JSFIDLE供参考: .字段验证错误{ 颜色:红色; } ng模式绑定未更新: 输入“asdf”,然后单击Cuba。ngPattern应该更新,您不应该看到“坏格式”。 国家 邮政编码 格式错误 要求的 //模块: 角度。模块('mod1',[]) .controller('ctrl1',['$scope',函数($scope){ //$scope.editAddr
.字段验证错误{
颜色:红色;
}
ng模式绑定未更新:
输入“asdf”,然后单击Cuba。ngPattern应该更新,您不应该看到“坏格式”。
国家
邮政编码
格式错误
要求的
//模块:
角度。模块('mod1',[])
.controller('ctrl1',['$scope',函数($scope){
//$scope.editAddress={postalCode:“12345”};
$scope.countries=[
{name:'United States',requiresPostal:true,postalRegEx:'^[0-9]{5}([-]?[0-9]{4})?$'},
//{name:'Canada',requiresPostal:true,postalRegEx:'^[a-yA-Y]\d[a-zA-Z]()?\d[a-zA-Z]\d$',
{name:'Cuba',requirePostal:false,postalRegEx:undefined}];
$scope.selectedCountry=$scope.countries[0];
}])
.filter('countryToPostalCodeRegex',[函数(){
var allowAllRegex=新的RegExp(“^.*”);
var escapeRegex=函数(str){
返回str.replace(/[\-\[\]\/\{\\}(\)\*\+\?\.\\\^\$\\\\\\\\\\;]/g,“\$&”);
}
返回函数(国家/地区){
如果(!国家){
返回Allowallegex;
}
如果(!country.requirePostal){
返回Allowallegex;
}
如果(!country.postalRegExObj){
country.postalRegExObj=新的RegExp(escapeRegex(country.postalRegEx),“i”);
}
返回国家/地区。postalRegExObj;
};
}]);
当前Angular不监视属性的更改,它只监视绑定值。有几个角度的问题需要进一步讨论。caitp的两个关键意见是:
角度的一般模式是不响应实际的变化
属性值,而是响应对绑定值的更改
及
这样做的问题是,当前的模式不是来自
解析表达式/范围变量,它只是一个字符串文本
进入一个regexp,因此观察对它的更改本质上意味着
观察DOM属性值的变化。我想我提到过
几周前关于这个的另一个问题。观察变化
对于实际的DOM属性,它与角度是完全不同的
通常是这样
从这些问题中得到一个线索,看看如何处理这个问题的一种方法是添加一个指令,用于监视ngPattern
属性的Angulareval()
。如果它看到变化,那么它可以评估ngPattern
regex和setValidity
这使我们能够动态监视属性值。以下是指令:
.directive('updatePattern', function() {
return {
require: "^ngModel",
link: function(scope,element,attrs,ctrl) {
scope.$watch(function() {
// Evaluate the ngPattern attribute against the current scope
return scope.$eval(attrs.ngPattern);
},
function(newval, oldval) {
//Get the value from `ngModel`
value = ctrl.$viewValue;
// And set validity on the model to true if the element
// is empty or passes the regex test
if (ctrl.$isEmpty(value) || newval.test(value)) {
ctrl.$setValidity('pattern', true);
return value;
} else {
ctrl.$setValidity('pattern', false);
return undefined;
}
});
}
}
});
我们将新的更新模式
指令添加到html中:
<input name="postalCode" type="text" class="form-control" data-ng-model="editAddress.postalCode" data-ng-required="selectedCountry.requiresPostal"
ng-pattern="selectedCountry | countryToPostalCodeRegex" maxlength="12" update-pattern />
来自@KayadDave的解决方案是一个完美的解决方案,但您可以使用一个变通方法:手动调用$setViewValue以强制ng模式评估:
<!-- Add ng-change function -->
<select name="country" class="form-control"
data-ng-model="selectedCountry"
data-ng-options="country as country.name for country in countries"
data-ng-required="true"
data-ng-change="updatePattern()"
>
</select>
我有一个简单的方法来解决这个问题 使用
模式
而不是ng模式
如果你有源代码,你会发现pattern
和ng pattern
是同一个指令
在模式
和ng模式
之间有两种不同:1. angular将观察模式变化。(这就是我们需要的!)
2.angular将在模式前面加上“$”和“$”
$scope.regex = '\\d\\d'; //angular will convert this to ^\d\d$
$scope.UPPERCASE = '\\D\\D';
HTML:
这会破坏其他验证吗?像required和ng max length?我只能通过将第一个watch函数返回到new RegExp
中的eval
来实现这一点。
$scope.updatePattern = function() {
var postalCode = $scope.genericAddressEntry.postalCode;
postalCode.$setViewValue(postalCode.$viewValue);
};
$scope.regex = '\\d\\d'; //angular will convert this to ^\d\d$
$scope.UPPERCASE = '\\D\\D';
<input name="test" pattern="regex">
<!-- I can use filter to change my wrong UPPERCASE regex to correct.-->
<input name="test2" pattern="UPPERCASE | lowercase">