gpt4 book ai didi

javascript - 如何仅从内部修改指令范围属性

转载 作者:行者123 更新时间:2023-11-28 08:14:17 24 4
gpt4 key购买 nike

我有一个自定义指令,需要另一个自定义指令作为父级:

 .directive('controlErrorContainer', function () {
return {
restrict: 'E',
templateUrl: 'template/common/control_error_container.html',
require: '^controlContainer',
...
});

control_error_container.html 如下所示:

<div class="label label-danger" ng-show="isValid" ng-transclude>
</div>

最终,使用这些标签的 html 页面将如下所示:

<control-container control-to-check="stuff">
<input id="stuff" name="stuff" ng-model="stuff" />
<control-error-container>
You have failed me for the last time admiral!
</control-error-container>
</control-container>

我的想法是,control-container 存储对其应该保存和检查的控件的引用,而 control-error-container 仅在观察到的 Controller 存在任何验证问题时才显示其中的错误。

我有一个问题,我希望 controlErrorContainer 在没有任何外部属性的情况下运行。如您所见,它有一个 ng-show 标记,并定义了“isValid”值。该值是不必要的,因为可以通过父自定义指令的容器获取控件有效性的值(我这样做)。这不起作用,我不知道如何使其工作,因为在创建 Controller 后,必须在某处定义它。如果我用 2 路绑定(bind)创建一个作用域,Angular 会抛出异常。

所以问题是如何在不强制用户创建不必要的属性的情况下完成这项工作?

最佳答案

据我了解,您正在尝试构建类似验证框架之类的东西。由于 Angular 已经提供了一个,所以我建议尝试使用它。

Angular 的 validation framework建立在 FormController 之上和NgModelController form内部缺少协作 Controller 和ngModel指令。

添加自定义验证器只是编写一条指令将验证函数挂接到框架中。这种验证器的一个例子是:

app.directive('validUserType', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attrs, ngModelCtrl) {
var allowAdmin = attrs.allowAdmin && attrs.allowAdmin === 'true';

if (ngModelCtrl) {
ngModelCtrl.$parsers.push(userTypeValidator);
ngModelCtrl.$formatters.push(userTypeValidator);
}

function userTypeValidator(value) {
if (!value || value === 'guest' || (allowAdmin && value === 'admin')) {
ngModelCtrl.$setValidity('validUserType', true);
return value;
} else {
ngModelCtrl.$setValidity('validUserType', false);
return;
}
}
}
};
});

您申请的是:

<input name="input" ng-model="userType" required valid-user-type allow-admin="true">

请注意,您可以拥有任意数量的验证器( required 也是 Angular 提供的验证器),它们与具有附加属性的普通指令( allow-admin="true" )没有什么不同。它之所以成为验证器,是因为它与 ngModel 集成的方式。 。您可以在用户提供输入时添加一个“解析器”,并在 JavaScript 代码更改值时添加一个格式化程序。除了验证之外,它还可以充当转换器,即转换字符串 -> 对象(在解析器中),反之亦然(在格式化程序中)。在这种情况下,您需要 2 个独立的函数,而不是通用的函数。

Angular 的框架负责处理剩下的所有事情。它在输入/特定验证器/表单级别维护有效性“标志”,可用于显示/隐藏验证消息或启用/禁用按钮。它还维护 CSS 类,可用于添加视觉糖和“脏”标志,以通知用户哪些字段已被编辑。更重要的是,它将只允许有效值(或 undefined )传播到您的模型,这意味着如果您的 Controller 中有类似的内容:

$scope.$watch('userType', function(userType) {
if (userType) {
// make ajax with userType
}
});

保证仅有效userType值将被发送到服务器。

底线:它已经提供了很多功能并且得到了官方维护,因此在它的基础上构建是有意义的。

看看这个 plunker (从 Angular 文档中制作了 plunker)。

当然,您可以使用 control-container 构建自己的验证框架和control-error-container 。您的示例缺少的是实际验证器如何连接到游戏中。我的偏好是将其应用在输入元素上,就像应用 Angular 验证器一样:

<control-container>
<input ng-model="userType" valid-user-type allow-admin="true"/>
<control-error-container>
You have failed me for the last time admiral!
</control-error-container>
</control-container>

valid-user-type是您的自定义验证器,它将其结果传达给 control-container然后从 control-container降至 control-error-container 。这 3 个指令类似于:

app.directive('controlContainer', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
controller: function() {
var controlErrorContainer = null;

this.setValid = function(value) {
if (controlErrorContainer) controlErrorContainer.setValid(value);
}

this.setControlErrorContainer = function(cec) {
controlErrorContainer = cec;
}
},
templateUrl: 'controlContainer.html'
};
});

app.directive('controlErrorContainer', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
require: ['controlErrorContainer', '^controlContainer'],
templateUrl: 'controlErrorContainer.html',
controller: ['$scope', function($scope) {
$scope.isValid = true;
this.setValid = function(value) {
$scope.isValid = value;
};
}],
link: function(scope, elem, attrs, controllers) {
var controlErrorContainer = controllers[0];
var controlContainer = controllers[1];
controlContainer.setControlErrorContainer(controlErrorContainer);
}
};
});

app.directive('validUserType', function() {
return {
restrict: 'A',
require: ['ngModel', '^controlContainer'],
link: function(scope, elem, attrs, controllers) {
var allowAdmin = attrs.allowAdmin && attrs.allowAdmin === 'true';

var ngModel = controllers[0];
var controlContainer = controllers[1];

scope.$watch(
function() {
return ngModel.$viewValue;
},
function(value) {
if (!value || value === 'guest' || (allowAdmin && value === 'admin')) {
controlContainer.setValid(true);
} else {
controlContainer.setValid(false);
}
}
);
}
};
});

可以做类似<control-container control-to-check="stuff">的事情但我认为找到“东西”及其值(value)并在其上运行验证器更加困难(我不明白你是如何定义它的)。

查看完整的plunker .

关于javascript - 如何仅从内部修改指令范围属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23802599/

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