【发布时间】:2015-09-09 02:14:38
【问题描述】:
我有一个自定义下拉指令,它具有 class 和 ng-model 等常用属性。
我决定扩展此控件以支持验证,现在需要包含可选属性,这些属性只有在程序员设置的情况下才应包含在输出模板中。
示例
我有一个部分工作的系统,在该系统中我将代码从模板 URL 中移到了我在帖子中调用的字符串连接中:指令的函数编译。
我宁愿将指令 HTML 留在模板中,但无法使其正常工作,所以我有这个解决方案。
问题:
- 这是编写具有动态属性的模板的最佳方式吗?
- 是否可以在将 HTML 保留在模板 URL 中时使其工作
- 我应该使用 compile => post 函数还是应该在链接函数中完成此操作
指令代码
'use strict';
angular.module(APP)
.directive('wkKeyLabelSelect', ["$compile",
function($compile) {
return {
restrict: 'EA',
replace: true,
scope: {
'class': '@', // Permanent - One Way Attribute
ngModel: '=', // Permanent - Two Way Attribute (Angular)
items: '=', // Permanent - Two Way Attribute (Custom)
id: '@', // Dynamic - One Way Attribute
name: '@', // Dynamic - One Way Attribute
ngRequired: '=', // Dynamic - Two Way Attribute (Angular)
},
//templateUrl: COMPONENTS_PATH + '/keyLabelSelect/keyLabelSelect.html',
controller: 'KeyLabelSelectController',
link: function (scope, element, attrs) {
//$compile(element)(scope);
},
compile: function (element, attrs) {
// name & ngRequired are not available in the compile scope
//element.replaceWith($compile(html)(scope));
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
},
post: function postLink(scope, iElement, iAttrs, controller) {
// Template goes here
var html =
'<select ' +
' class="{{class}}"' +
(scope.id ? ' id="{{id}}"' : "") +
(scope.name ? ' name="{{name}}"' : "") +
(scope.ngRequired ? ' ng-required="true"' : "") +
' ng-model="ngModel"' +
' ng-options="item.key as item.label for item in items"' +
'>' +
'</select>';
iElement.replaceWith($compile(html)(scope));
}
}
}
};
}
]);
指令控制器代码
angular.module(APP)
.controller('KeyLabelSelectController', ['$scope', function ($scope) {
$scope.klass = typeof $scope.klass === 'undefined' ? 'form-control' : $scope.klass;
console.log($scope.ngModel);
console.log($scope.items);
}]);
用于运行指令的 HTML
<div class="form-group" ng-class="{ 'has-error': editForm.state.$touched && editForm.name.$invalid }">
<label class="col-md-3 control-label">State</label>
<div class="col-md-9">
<wk-key-label-select id="state" name="state"
ng-required="true"
ng-model="model.entity.state"
class="form-control input-sm"
items="model.lookups.job_state">
</wk-key-label-select>
<div class="help-block" ng-messages="editForm.state.$error">
<p ng-message="required">Job State is required.</p>
</div>
</div>
</div>
我的原始模板 URL 内容,当前未使用
<!-- This is now deprecated in place of inline string -->
<!-- How could I use a in place of string concatenation -->
<select class="{{klass}}"
name="{{name}}"
ng-model="ngModel"
ng-options="item.key as item.label for item in items"></select>
【问题讨论】:
-
为什么会有和你粘贴的代码一模一样的代码截图?此外,您似乎正在实施custom input control,但您应该正确使用
ngModelController- 执行scope: {ngModel: "="}是错误的方法。 -
图片标注了具体问题,指向有问题的代码。这就是为什么它看起来像重复的原因,我有代码和带注释的图像
-
我不知道 ngModelController,现在正在研究它
-
针对“应该是peroperly使用ngModelController”,我做了一些研究,因为我没有做自定义验证或复杂的属性,没有必要介绍使用ngModelController的复杂性。我的意见来源是:radify.io/blog/… 和 bennadel.com/blog/…
-
您正在引入自定义输入控件。当然,它在其模板中使用现有的输入控件,但如果您希望它支持
ngModel模型(即支持其他验证器、自定义解析器、与<form>集成等),那么使用 @ 是个好主意987654336@。您不必必须,但这是最有角度的方式。总的来说,您是在问一个 XY 问题 - 相反,请解释您正在尝试使用普通<select>无法提供的自定义下拉菜单实现的目标
标签: javascript angularjs angularjs-directive