AngularJS 使用从服务中填充的 ng-options 的自定义指令
AngularJS Custom Directive using ng-options populated from service
我真的遇到了困难,我知道我可能在这里遗漏了一些东西,但我被困住了,需要帮助。我想做的是使用服务来填充 ng-options 指令中的选项;但是,ng-options 在自定义指令内,我已经尝试了从跟踪到在指令外、指令内测试它的所有方法。有人可以看一下这段代码,看看你是否能发现我遗漏的东西吗?任何帮助是极大的赞赏。只要执行对 ng-model 的更新,它就会起作用;然而,在页面登陆和记录 selection 时,它最初不会 select 正确的选项,但如果我通过 out 跟踪,它将使用正确的 selection 初始化,它只是不会更新 ng-model when/if 我会那样做。
angular
.module('app')
.controller('mainCtrl', ['acctList', 'CONSTANTS', 'FORMFIELDS', function(acctList, CONSTANTS, FORMFIELDS) {
var mainCtrl = this;
mainCtrl.form = {};
mainCtrl.formFields = FORMFIELDS;
mainCtrl.currentRecord = null;
mainCtrl.editedRecord = {};
mainCtrl.setCurrentRecord = function(value) {
mainCtrl.currentRecord = value;
mainCtrl.editedRecord = angular.copy(mainCtrl.currentRecord);
};
mainCtrl.statuses = CONSTANTS.statuses;
}])
.value('FORMFIELDS', [
{
key: 'active_flag',
inputtype: 'select',
type: 'text',
class: 'form-control',
id: 'activeFl',
name: 'activeFl',
placeholder: 'Active Flag',
required: true,
maxlength: 1,
disabled: false,
labelfor: 'inputActiveFl',
labeltext: 'Active Flag',
field: 'mainCtrl.editedRecord.ACTIVE_FL',
options: 'list as list.desc for list in mainCtrl.statuses track by list.value'
}
])
.value('CONSTANTS',
{
statuses: [
{
id: 1,
value: "Y",
desc: "Active"
},
{
id: 2,
value: "N",
desc: "Inactive"
}
]
}
)
.directive('formTemplate', ['$compile', function($compile) {
function linker(scope, element, attr) {
scope.$watch(attr.modeltemp, function(modeltemp) {
// if ngModel already equals modeltemp or modeltemp doesn't exist, return
if (attr.ngModel == modeltemp || !modeltemp) return;
// remove all attributes to prevent duplication
element.removeAttr('placeholder');
element.removeAttr('type');
element.removeAttr('class');
element.removeAttr('id');
element.removeAttr('name');
element.removeAttr('ng-required');
element.removeAttr('maxlength');
element.removeAttr('ng-disabled');
// add the ng-model attribute presently tied to modeltemp
element.attr('ng-model', modeltemp);
// if modeltemp is blank, then remove ng-model, as it would be null
if (modeltemp == '') {
element.removeAttr('ng-model');
}
// Unbind all previous event handlers, this is
// necessary to remove previously linked models.
element.off();
// run a compile on the element, injecting scope, to reconstruct the element
$compile(element)(scope);
});
console.log(scope.acctCtrl);
}
// dynamic templating function associated with the templateUrl in the DDO
function template (tElement, tAttrs) {
// set the type variable equal to the value from the tAttr for 'inputtype' coming from the view
var type = tAttrs['inputtype'];
// just declaring the return variable for cleanliness
var tpl;
// begin the switch-case statement for each inputtype, then set it's return variable equal to the respective url
switch(type) {
case 'input':
tpl = '/common/directives/formTemplate/formTemplate.template.html';
break;
case 'select':
tpl = '/common/directives/formTemplate/formTemplateSelect.template.html';
break;
default:
tpl = '/common/directives/formTemplate/formTemplate.template.html';
break;
}
return tpl;
}
return {
restrict: 'EA',
replace: true,
templateUrl: template,
link: linker
};
}])
<form class="form-horizontal" ng-submit="submit()" name="mainCtrl.form.newAcctForm">
<div class="col-lg-6 form-fields" ng-repeat="fields in mainCtrl.formFields" ng-class="{ 'has-error': mainCtrl.form.newAcctForm.{{fields.name}}.$dirty }">
<label class="control-label" for="{{fields.labelfor}}">{{fields.labeltext}}</label>
<div form-template modeltemp="fields.field" inputtype="{{fields.inputtype}}"></div>
</div>
</form>
<select class="{{fields.class}}" id="{{fields.id}}" name="{{fields.name}}" ng-options="{{fields.options}}" ng-required="{{fields.required}}" maxlength="{{fields.maxlength}}" ng-disabled="{{fields.disabled}}">
<option value="">Please select...</option>
</select>
虽然这确实有效,但您是否考虑过使用生命周期挂钩,等到视图具有 loaded/initialized 之后?您的解决方案有效,但有点像在蚁丘上使用火箭发射器。
我真的遇到了困难,我知道我可能在这里遗漏了一些东西,但我被困住了,需要帮助。我想做的是使用服务来填充 ng-options 指令中的选项;但是,ng-options 在自定义指令内,我已经尝试了从跟踪到在指令外、指令内测试它的所有方法。有人可以看一下这段代码,看看你是否能发现我遗漏的东西吗?任何帮助是极大的赞赏。只要执行对 ng-model 的更新,它就会起作用;然而,在页面登陆和记录 selection 时,它最初不会 select 正确的选项,但如果我通过 out 跟踪,它将使用正确的 selection 初始化,它只是不会更新 ng-model when/if 我会那样做。
angular
.module('app')
.controller('mainCtrl', ['acctList', 'CONSTANTS', 'FORMFIELDS', function(acctList, CONSTANTS, FORMFIELDS) {
var mainCtrl = this;
mainCtrl.form = {};
mainCtrl.formFields = FORMFIELDS;
mainCtrl.currentRecord = null;
mainCtrl.editedRecord = {};
mainCtrl.setCurrentRecord = function(value) {
mainCtrl.currentRecord = value;
mainCtrl.editedRecord = angular.copy(mainCtrl.currentRecord);
};
mainCtrl.statuses = CONSTANTS.statuses;
}])
.value('FORMFIELDS', [
{
key: 'active_flag',
inputtype: 'select',
type: 'text',
class: 'form-control',
id: 'activeFl',
name: 'activeFl',
placeholder: 'Active Flag',
required: true,
maxlength: 1,
disabled: false,
labelfor: 'inputActiveFl',
labeltext: 'Active Flag',
field: 'mainCtrl.editedRecord.ACTIVE_FL',
options: 'list as list.desc for list in mainCtrl.statuses track by list.value'
}
])
.value('CONSTANTS',
{
statuses: [
{
id: 1,
value: "Y",
desc: "Active"
},
{
id: 2,
value: "N",
desc: "Inactive"
}
]
}
)
.directive('formTemplate', ['$compile', function($compile) {
function linker(scope, element, attr) {
scope.$watch(attr.modeltemp, function(modeltemp) {
// if ngModel already equals modeltemp or modeltemp doesn't exist, return
if (attr.ngModel == modeltemp || !modeltemp) return;
// remove all attributes to prevent duplication
element.removeAttr('placeholder');
element.removeAttr('type');
element.removeAttr('class');
element.removeAttr('id');
element.removeAttr('name');
element.removeAttr('ng-required');
element.removeAttr('maxlength');
element.removeAttr('ng-disabled');
// add the ng-model attribute presently tied to modeltemp
element.attr('ng-model', modeltemp);
// if modeltemp is blank, then remove ng-model, as it would be null
if (modeltemp == '') {
element.removeAttr('ng-model');
}
// Unbind all previous event handlers, this is
// necessary to remove previously linked models.
element.off();
// run a compile on the element, injecting scope, to reconstruct the element
$compile(element)(scope);
});
console.log(scope.acctCtrl);
}
// dynamic templating function associated with the templateUrl in the DDO
function template (tElement, tAttrs) {
// set the type variable equal to the value from the tAttr for 'inputtype' coming from the view
var type = tAttrs['inputtype'];
// just declaring the return variable for cleanliness
var tpl;
// begin the switch-case statement for each inputtype, then set it's return variable equal to the respective url
switch(type) {
case 'input':
tpl = '/common/directives/formTemplate/formTemplate.template.html';
break;
case 'select':
tpl = '/common/directives/formTemplate/formTemplateSelect.template.html';
break;
default:
tpl = '/common/directives/formTemplate/formTemplate.template.html';
break;
}
return tpl;
}
return {
restrict: 'EA',
replace: true,
templateUrl: template,
link: linker
};
}])
<form class="form-horizontal" ng-submit="submit()" name="mainCtrl.form.newAcctForm">
<div class="col-lg-6 form-fields" ng-repeat="fields in mainCtrl.formFields" ng-class="{ 'has-error': mainCtrl.form.newAcctForm.{{fields.name}}.$dirty }">
<label class="control-label" for="{{fields.labelfor}}">{{fields.labeltext}}</label>
<div form-template modeltemp="fields.field" inputtype="{{fields.inputtype}}"></div>
</div>
</form>
<select class="{{fields.class}}" id="{{fields.id}}" name="{{fields.name}}" ng-options="{{fields.options}}" ng-required="{{fields.required}}" maxlength="{{fields.maxlength}}" ng-disabled="{{fields.disabled}}">
<option value="">Please select...</option>
</select>
虽然这确实有效,但您是否考虑过使用生命周期挂钩,等到视图具有 loaded/initialized 之后?您的解决方案有效,但有点像在蚁丘上使用火箭发射器。