지시문 내 템플리트 사용자 정의
다음과 같은 Bootstrap의 마크업을 사용하는 폼이 있습니다.
<form class="form-horizontal">
<fieldset>
<legend>Legend text</legend>
<div class="control-group">
<label class="control-label" for="nameInput">Name</label>
<div class="controls">
<input type="text" class="input-xlarge" id="nameInput">
<p class="help-block">Supporting help text</p>
</div>
</div>
</fieldset>
</form>
여기에 보일러 플레이트 코드가 많이 들어있기 때문에 다음과 같은 새로운 명령어인 폼 입력으로 줄이고 싶습니다.
<form-input label="Name" form-id="nameInput"></form-input>
는 다음을 생성합니다.
<div class="control-group">
<label class="control-label" for="nameInput">Name</label>
<div class="controls">
<input type="text" class="input-xlarge" id="nameInput">
</div>
</div>
간단한 템플릿으로 이 정도 작업을 할 수 있습니다.
angular.module('formComponents', [])
.directive('formInput', function() {
return {
restrict: 'E',
scope: {
label: 'bind',
formId: 'bind'
},
template: '<div class="control-group">' +
'<label class="control-label" for="{{formId}}">{{label}}</label>' +
'<div class="controls">' +
'<input type="text" class="input-xlarge" id="{{formId}}" name="{{formId}}">' +
'</div>' +
'</div>'
}
})
다만, 보다 고도의 기능을 추가하게 되면, 막히게 됩니다.
템플릿에서 기본값을 지원하려면 어떻게 해야 합니까?
지시문에 "type" 매개 변수를 선택적 속성으로 표시하려고 합니다. 예:
<form-input label="Password" form-id="password" type="password"/></form-input>
<form-input label="Email address" form-id="emailAddress" type="email" /></form-input>
단, 아무것도 지정되어 있지 않은 경우 디폴트로"text"어떻게 지원하면 좋을까요?
애트리뷰트의 유무에 따라 템플릿을 커스터마이즈하려면 어떻게 해야 합니까?
또, 「필수」아트리뷰트가 있으면 서포트할 수 있으면 좋겠습니다.예:
<form-input label="Email address" form-id="emailAddress" type="email" required/></form-input>
한다면required지시문에 있습니다. 생성된 명령어에 추가하고 싶습니다.<input />그 이외의 경우에는 무시해 주세요.어떻게 해야 할지 모르겠어요.
이러한 요건이 단순한 템플릿을 넘어 컴파일 전 단계를 사용해야 할 것 같습니다만, 어디서부터 시작해야 할지 막막합니다.
angular.module('formComponents', [])
.directive('formInput', function() {
return {
restrict: 'E',
compile: function(element, attrs) {
var type = attrs.type || 'text';
var required = attrs.hasOwnProperty('required') ? "required='required'" : "";
var htmlText = '<div class="control-group">' +
'<label class="control-label" for="' + attrs.formId + '">' + attrs.label + '</label>' +
'<div class="controls">' +
'<input type="' + type + '" class="input-xlarge" id="' + attrs.formId + '" name="' + attrs.formId + '" ' + required + '>' +
'</div>' +
'</div>';
element.replaceWith(htmlText);
}
};
})
Misko가 제안한 솔루션을 사용하려고 했지만, 제 상황에서는 템플릿 html에 통합해야 하는 속성 자체가 지시사항이었습니다.
유감스럽게도 결과 템플릿에서 참조되는 모든 지시어가 올바르게 동작하지는 않았습니다.각도 코드를 조사하여 근본 원인을 찾을 시간이 부족했지만 해결 방법을 찾아냈습니다. 이것이 잠재적으로 도움이 될 수 있습니다.
해결책은 템플릿 html을 만드는 코드를 컴파일 함수에서 템플릿 함수로 이동하는 것이었습니다.위의 코드에 근거한 예:
angular.module('formComponents', [])
.directive('formInput', function() {
return {
restrict: 'E',
template: function(element, attrs) {
var type = attrs.type || 'text';
var required = attrs.hasOwnProperty('required') ? "required='required'" : "";
var htmlText = '<div class="control-group">' +
'<label class="control-label" for="' + attrs.formId + '">' + attrs.label + '</label>' +
'<div class="controls">' +
'<input type="' + type + '" class="input-xlarge" id="' + attrs.formId + '" name="' + attrs.formId + '" ' + required + '>' +
'</div>' +
'</div>';
return htmlText;
}
compile: function(element, attrs)
{
//do whatever else is necessary
}
}
})
유감스럽게도 위의 답변은 효과가 없습니다.특히 컴파일 단계에서는 범위에 액세스할 수 없으므로 동적 속성에 따라 필드를 사용자 정의할 수 없습니다.링크 스테이지를 사용하는 것이 가장 유연하다고 생각됩니다(비동기적으로 dom을 작성하는 등).다음의 어프로치는, 다음의 점에 대응하고 있습니다.
<!-- Usage: -->
<form>
<form-field ng-model="formModel[field.attr]" field="field" ng-repeat="field in fields">
</form>
// directive
angular.module('app')
.directive('formField', function($compile, $parse) {
return {
restrict: 'E',
compile: function(element, attrs) {
var fieldGetter = $parse(attrs.field);
return function (scope, element, attrs) {
var template, field, id;
field = fieldGetter(scope);
template = '..your dom structure here...'
element.replaceWith($compile(template)(scope));
}
}
}
})
좀 더 완벽한 코드와 접근법에 대한 기록을 가지고 있는 요지를 만들었습니다.
이게 내가 결국 사용한 것이다.
저는 Angular JS에 익숙하지 않기 때문에 더 나은 대안 솔루션을 보고 싶습니다.
angular.module('formComponents', [])
.directive('formInput', function() {
return {
restrict: 'E',
scope: {},
link: function(scope, element, attrs)
{
var type = attrs.type || 'text';
var required = attrs.hasOwnProperty('required') ? "required='required'" : "";
var htmlText = '<div class="control-group">' +
'<label class="control-label" for="' + attrs.formId + '">' + attrs.label + '</label>' +
'<div class="controls">' +
'<input type="' + type + '" class="input-xlarge" id="' + attrs.formId + '" name="' + attrs.formId + '" ' + required + '>' +
'</div>' +
'</div>';
element.html(htmlText);
}
}
})
사용 예:
<form-input label="Application Name" form-id="appName" required/></form-input>
<form-input type="email" label="Email address" form-id="emailAddress" required/></form-input>
<form-input type="password" label="Password" form-id="password" /></form-input>
언급URL : https://stackoverflow.com/questions/10629238/customizing-the-template-within-a-directive
'programing' 카테고리의 다른 글
| C#에서 사전을 JSON 문자열로 변환하려면 어떻게 해야 하나요? (0) | 2023.03.01 |
|---|---|
| '읽기 전용' 유형에 '값' 속성이 없습니다.< { } > (0) | 2023.03.01 |
| 색인 페이지의 WordPress wp_title 공백 (0) | 2023.03.01 |
| 스프링 3 주석을 사용하여 심플한 공장 패턴 구현 (0) | 2023.03.01 |
| 루비의 JSON 파일에서 구문 분석 및 중첩된 해시에서 숫자 추출 (0) | 2023.03.01 |