- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个自定义指令,用于根据指令中也需要提供的其他值来验证输入字段。我通过使用带有范围变量的隔离范围来做到这一点。更具体地说,我想将产品的客户价格(即其净价)与购买价格进行比较,如果差异为负(客户价格设置为 0 除外),我想让客户- 价格输入(及其周围形式)无效。这是我的指令:
export class CheckMarkupDirective implements ng.IDirective {
public static create(): ng.IDirective {
return {
restrict: "A",
require: "ngModel",
scope: {
netPrice: "<",
markupAmount: "<"
},
link: (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, ngModelCtrl: ng.INgModelController) => {
let netPrice: number;
let markupAmount: number;
scope.$watchGroup(["netPrice", "markupAmount"], (newValues, oldValues) => {
[netPrice, markupAmount] = newValues;
if (markupAmount >= 0) {
ngModelCtrl.$setValidity("markup", true);
} else {
ngModelCtrl.$setValidity("markup", netPrice === 0);
}
ngModelCtrl.$validate();
});
}
};
}
}
这就是我在由表单标签包围的 ng-form div 中使用它的方式:
<input type="text" id="customer-price" name="customerPrice"
ng-model="ctrl.product.customerPrice"
ng-change="ctrl.customerPriceChangeDetected()"
check-markup markup-amount="ctrl.product.markupAmount"
net-price="ctrl.product.netPrice" />
它可以工作,但问题是验证部分似乎“计时错误”,这意味着如果我输入一个导致“标记”第一次变为负值的值,那么表单的 $invalid值设置为 false。但是,当接下来输入为负数时,验证将启动并起作用。我认为我的问题是我在不同步骤之间进行了大量计算,但我很难知道是什么导致验证如此失败。我想我希望有人对 Angular JS 机制有更深入的了解,并告诉我我是否做了一些明显错误的事情。提前致谢,如果我的描述有点含糊,抱歉。
编辑:我想还包括在 ng-change 上触发的方法:
public customerPriceChangeDetected(): void {
this.setNetPriceFromCustomerPrice();
this.setMarkup();
this.changeDetected();
}
private setNetPriceFromCustomerPrice(): void {
let customerPrice = this.product.customerPrice;
let vatRate = this.product.vatRate;
let netPrice = (customerPrice / (1 + vatRate));
this.product.netPrice = parseFloat(accounting.toFixed(netPrice, 2));
}
private setMarkup(): void {
let purchasePrice = this.product.purchasePrice;
let markupAmount = this.product.netPrice - purchasePrice;
this.product.markupAmount = markupAmount;
this.product.markupPercent = markupAmount / purchasePrice;
}
public changeDetected(): void {
let isValid = this.validationService ? this.validationService.isValid : false;
this.toggleSaveButton(isValid);
}
验证服务 getter 基本上返回 form.$valid 并且对于我所有其他自定义验证器来说工作得非常好。
编辑 2: 添加了屏幕截图,显示周围的 ng-form 标记似乎将其 $invalid 属性至少设置为 true:
编辑3:这是转译后的 JS:
var CheckMarkupDirective = (function () {
function CheckMarkupDirective() {
}
CheckMarkupDirective.create = function () {
return {
restrict: "A",
require: "ngModel",
scope: {
netPrice: "<",
markupAmount: "<"
},
link: function (scope, element, attrs, ngModelCtrl) {
var netPrice;
var markupAmount;
scope.$watchGroup(["netPrice", "markupAmount"], function (newValues, oldValues) {
netPrice = newValues[0], markupAmount = newValues[1];
if (!markupAmount || !netPrice)
return;
if (markupAmount >= 0) {
ngModelCtrl.$setValidity("markup", true);
}
else {
ngModelCtrl.$setValidity("markup", netPrice === 0);
}
//ngModelCtrl.$validate();
});
}
};
};
return CheckMarkupDirective; }());
...这是我的 html 的精简版本:
<form autocomplete="off" class="form-horizontal" role="form" name="productDetailsForm" novalidate data-ng-init="ctrl.setForm(this,'productDetailsForm')">
<div data-ng-form="section2">
<div class="form-group">
<label for="purchase-price" class="col-sm-4 control-label">Purchase price</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="purchase-price" name="purchasePrice"
data-ng-model="ctrl.product.purchasePrice"
data-ng-change="ctrl.purchasePriceChangeDetected();"
data-decimal="Currency" />
</div>
</div>
<div class="form-group">
<label for="vat-rate" class="col-sm-4 control-label">VAT rate</label>
<div class="col-sm-4">
<select class="form-control" id="vat-rate"
data-ng-model="ctrl.product.vatRate"
data-ng-change="ctrl.vatRateChangeDetected()"
data-ng-options="vatRate.value as vatRate.text for vatRate in ctrl.vatRates"></select>
</div>
</div>
<div class="form-group" data-has-error-feedback="productDetailsForm.section2.customerPrice">
<label for="customer-price" class="col-sm-4 control-label">Customer price</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="customer-price" name="customerPrice"
data-ng-model="ctrl.product.customerPrice"
data-ng-change="ctrl.customerPriceChangeDetected();"
data-decimal="Currency"
data-check-markup
data-markup-amount="ctrl.product.markupAmount"
data-net-price="ctrl.product.netPrice" />
<invalid-feedback item="productDetailsForm.section2.customerPrice"></invalid-feedback>
<validation-feedback type="markup" item="productDetailsForm.section2.customerPrice" data-l10n-bind="ADMINISTRATION.PRODUCTS.NET_PRICE.INVALID"></validation-feedback>
</div>
<div class="col-sm-4">
<div class="form-group" style="margin-bottom: 0;">
<label for="net-price" class="col-lg-5 col-md-5 col-sm-5 col-xs-5" style="font-weight: normal; margin-top: 7px;">
<span data-l10n-bind="ADMINISTRATION.PRODUCTS.NET_PRICE"></span>
</label>
<label class="col-lg-7 col-md-7 col-sm-7 col-xs-7" style="font-weight: normal; margin-top: 7px;">
<span id="net-price">{{ ctrl.product.netPrice | currency }}</span>
</label>
</div>
</div>
</div>
<div class="form-group" data-has-error-feedback="productDetailsForm.section2.markup">
<label for="markup-amount" class="col-sm-4 col-xs-4 control-label">Markup</label>
<div class="col-sm-8 col-xs-8">
<label id="markup-percent" class="control-label" data-ng-class="{'text-danger': ctrl.product.markupPercent < 0}">
{{ ctrl.product.markupPercent * 100 | number: 2 }}%
</label>
<label id="markup-amount" class="control-label" data-ng-class="{'text-danger': ctrl.product.markupAmount < 0}">
({{ ctrl.product.markupAmount | currency }})
</label>
</div>
</div>
</div>
我已在指令中的 watch 内放置了断点,由于某些奇怪的原因,当我第一次在客户价格输入中输入新值时, watch 似乎没有触发。相反,我发现自己直接进入了changeDetected()方法。我现在真的很困惑。我认为这个问题与验证之前触发的 ng-change 指令有关。我可能有一个错误的逻辑,导致在指令有时间实际改变有效性之前触发我的验证服务的 isValid 检查。
最佳答案
尝试删除隔离范围并直接评估属性:
export class CheckMarkupDirective implements ng.IDirective {
public static create(): ng.IDirective {
return {
restrict: "A",
require: "ngModel",
/* REMOVE isolate scope
scope: {
netPrice: "<",
markupAmount: "<"
},
*/
link: (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, ngModelCtrl: ng.INgModelController) => {
let netPrice: number;
let markupAmount: number;
//scope.$watchGroup(["netPrice", "markupAmount"],
//WATCH attributes directly
scope.$watchGroup([attrs.netPrice, attrs.markupAmount], (newValues, oldValues) => {
[netPrice, markupAmount] = newValues;
if (markupAmount >= 0) {
ngModelCtrl.$setValidity("markup", true);
} else {
ngModelCtrl.$setValidity("markup", netPrice === 0);
}
ngModelCtrl.$validate();
});
}
};
}
}
input
、ng-model
和 ng-change
指令需要一个没有作用域的元素。这消除了一次性绑定(bind)观察者以及隔离范围对抗这些指令的复杂性。
关于angularjs - Angular 1.6 使用 $setValidity 自定义验证指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41323893/
我使用指令来检查电子邮件是否已在我的数据库中注册。 app.directive('uniqueEmail', function($http) { var toId; return {
我正在尝试一个简单的 Angular 日期验证,其中当选择的日期大于当前日期时,todate在提交时给出错误消息。但输出并不如预期。选择任何日期时都会出错,但条件在调试断点中正确检查。 骗子链接“:p
我的 Angular JS 应用程序中有以下代码块。 (这是庞大代码的简化版本) HTML JS文件 app.controller('moveCtrl',
我正在 Angular 中创建一个包含三个输入的注册表单:email、password 和 passwordConfirm。我的 Controller 看起来像这样: app.controller('
我不确定为什么 setValidators 在我的以下代码中不起作用。我不确定问题是什么,因为当我根据需要设置 formControl 时它没有任何效果。我想要实现的是在选择特定选项时动态设置一些所需
我有这个元素: 回调执行: $scope.myForm.azurerepo.$setValidity('azurerepo',false); 如果我输入数据并从输入中出来,它会将其设置为无效。 如果
我有这样的指令: .directive('validRegex', function() { return { restrict: 'A', require: 'n
我正在使用 AngularJs 1.2。我的 $setValidity 有问题。 我有一个带有 ng-repeat 的表单输入: 现在我需要在某些指定输入上使用 $setValidity
我正在尝试使用 $setValidity在指令中的元素上。我发现的所有示例似乎都将它设置在 Controller 上...... 我在表单验证上 fork 了一个 JS fiddle,并尝试了很多东西
我正在尝试构建一个自定义指令(基于我看到的示例)以确保确认密码正确。我在 $setValidity 标签上遇到了一些麻烦,尽管我所有的 console.log() 都执行并打印出来,但有效性似乎没有被
我有一些函数可以动态分配验证 // set validation from sports response. private static setValidation(sportsItem: Sp
我有指令验证用户输入的相同密码。但在指令内部我想为两个输入元素setValidity = true .directive('equalsTo', function() { return
我正在使用设置表单有效性的指令。一切都相应地进行,但是自定义有效性的 bool 值不会立即返回,确切地说,它需要执行额外的按键操作。顺便说一句,我使用“element.blur”来设置自定义有效性。
例如,我有这段代码初始化 word 验证器 minlength 6 个字符。然后当 word 的长度 >4 时,minlength 被设置为 8 个字符。 问题是,当您输入第五个字符时,更改不会立即可
例如,我有这段代码初始化 word 验证器 minlength 6 个字符。然后当 word 的长度 >4 时,minlength 被设置为 8 个字符。 问题是,当您输入第五个字符时,更改不会立即可
我想我遗漏了 $validators 和 $setValidity 的东西(据我所知,做完全相同的事情所以你不需要两者 - 请更正如果我错了,我)。无论我是否有 $validators 语句,我都会将
我正在使用使用指令实现的自定义表单输入验证器。在指令中,验证事件绑定(bind)到输入的模糊事件。因此,在模糊时,它使用 $setValidity 设置模型的有效性。但是,在模型的值再次修改之前,$v
我正在使用 FluentValidation 来验证对象内部的集合,将集合项的元素与父对象的元素进行比较。 目标输出是接收集合中每个失败项的 ValidationFailures,而不仅仅是集合失败。
我正在尝试对文件更改进行一些验证。这是我的代码: View /模板 Error Selected file is too large Unsupported File type Controller
我有一个父组件,我在其中创建一个 FormControl 数组并使用 Validations.required Validator 对其进行初始化。 在子组件中,我根据来自父组件的输入(真/假)添加一
我是一名优秀的程序员,十分优秀!