我不确定我是否会以正确的方式进行此操作。我使用的ui-select
指令似乎不支持HTML required
指令。所以我建立了自己的ui-select-required
。似乎我无法使用隔离范围,因为ui-select
已经实例化隔离范围。
我想让ui-select-required
将函数作为属性。如果属性存在,则应使用此函数的返回值进行验证。如果该属性不存在,那么它应该在存在值时进行验证。这都是组件的一部分。
product_details.js
angular
.module('ProductComponents')
.component('productDetails', {
bindings:{
product: '=product',
},
templateUrl: "/template/admin/products/details",
controllerAs: 'prodDetails',
controller: [
'v3Stitcher',
'AjaxLoaderSvc',
'ModelInformationSvc',
'$filter',
'$http',
'current_site',
function(
v3Stitcher,
AjaxLoaderSvc,
ModelInformationSvc,
$filter,
$http,
current_site
){
var prodDetails = this;
...
prodDetails.templateRequired = function(){
// Product types requiring a template
// 3 - customizable_downloadable
// 6 - static_variable_downloadable
var productTypes = [3, 6];
// Specification types requiring a template
var specificationTypes = ["print_on_demand"];
if(productTypes.indexOf(prodDetails.product.product_type) > -1){
return true;
}
if(specificationTypes.indexOf(prodDetails.specification.specification_type) > -1){
console.log('here'); // this gets called
return true;
}
return false;
};
.directive('uiSelectRequired',function(){
return {
restrict:'A',
require:'ngModel',
link:function(scope, elem, attrs, ctrl){
var form = angular.element(document).find('form');
var input = angular.element(elem.find('input')[0]);
var requiredFn = scope[attrs['requiredFn']];
if(requiredFn){
ctrl.$validators.uiSelectRequired = function(){
return requiredFn();
};
} else {
ctrl.$validators.uiSelectRequired = function(modelValue){
return !ctrl.$isEmpty(modelValue)
};
}
form.on('submit', function(){
if(ctrl.$invalid){
elem.find('span').removeClass('ng-valid').addClass('ng-invalid');
}
});
elem.on('change', function(){
if(ctrl.$invalid){
elem.find('span').removeClass('ng-invalid').addClass('ng-valid');
}
});
}
};
});
details.slim
label(ng-class="{'label label-danger': prodDetails.templateRequired()}")
| Template
ui-select(ng-model="prodDetails.product.template_id" name="template" ng-model-options="{ debounce: { default:500, blur: 0 } }" ui-select-required required-fn="prodDetails.templateRequired")
ui-select-match(placeholder="Search Templates...")
| {{$select.selected.name}}
ui-select-choices(position="down" repeat="template.id as template in prodDetails.templates" refresh="prodDetails.refreshTemplates($select.search)" minimum-input-length="1" refresh-delay="0")
| {{ template.name }}
br
| id: {{template.id}}
br
| created: {{template.created_at | date : 'yyyy-MM-dd'}}
我遇到的问题是变量requireFn
未定义。但是,如果在HTML中我单独发送控制器变量prodDetails
,则requireFn
具有正确的控制器变量值。
答案 0 :(得分:0)
我认为你的问题是:
我想如果你改变这个:
var requiredFn = scope[attrs['requiredFn']];
为:
var requiredFn = scope.$eval(attrs.requiredFn);
你应该得到你想要的东西。这假设已将templateRequired
属性添加到productDetails组件的控制器实例中。
重申一下,您的问题是您直接在隔离范围本身上寻找属性,并将其添加到控制器参考中。通过执行scope.$eval
,您将基本上解析路径prodDetails.templateRequired
- 这将有希望解析为您希望首先获得的函数引用。
编辑:因此,评论中您问题的第二部分让我相信您从不需要将功能转换为具有隔离范围的指令。我认为你要做的是有条件地使模板模型成为必需。 Angular已通过必需和ng-required指令为您提供此功能。你在问题中说明这些在ui-select上是不可用的,但它们是" helper"使用ngModel的指令。我相信this是我想要做的事情的一个主要工作示例,我切换到所需的/ ng-required并消除了对自定义指令的需求。