AngularJS:在使用指令应用 select 下拉到页面时设置默认 select 选项
AngularJS: Set default select option when using directive to apply select drop down to page
EDIT/UPDATE
我为这个问题添加了一个plunker:
http://plnkr.co/edit/mlYKJQc7zQR0dsvDswMo
我正在将上一页的数据加载到我的页面控制器中的 $scope.visit 中。我想要一个指令,该指令使用数据库中的选项在页面上构造和加载 select 元素。这是我目前所拥有的:
app.directive('popList', ['$http', function($http) {
'use strict';
var directive = {
restrict: 'EA',
link: link,
scope: {
popList: '='
},
template: function(elem,attrs) {
return '<select '+
'ng-model="'+attrs.model+'" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
}
};
return directive;
function link(scope, elem, attrs, ctrl) {
var data = {
sTableName: attrs.tbl
};
$http.post('ddl.asmx/populateDDL',data).
then(function(response) {
console.log('This is the value I want to set it to '+scope.$parent.visit.data.state_id);
//ddlOpts loads with no problem
scope.ddlOpts = response.data.d;
});
}
}]);
然后 HTML 看起来像这样:
<div style="width: 5%" class="tableLabel">State</div>
<div
style="width: 27%;"
class="tableInput"
model="visit.data.state_id"
tbl="tblStates"
pop-list="states"
>
</div>
本质上,我传递了包含下拉选项的 table 的名称。我还传入了模型,它将告诉 select 默认值是什么(如果它有的话)
我可以毫无问题地将数据作为选项加载到 select 元素中。我已经检查了 ng-model 以确保我有正确的值来匹配 ng-value。我已经尝试过 ng-repeat,然后从头开始使用 ng-options,但我终生无法获得 select 选项来将默认值设置为 ng-model 值。
我开始认为这是因为 select 的构建范围与控制器将数据设置为 $scope.visit 的范围不同。有人可以解释为什么这两个范围不能相互识别,或者只是解释为什么我不能将我的默认值设置为存储在 ng-model 中的值吗?
这里是页面控制器,以备不时之需:
app.controller('demographicsFormCtrl', function($rootScope, $scope, $cookies, $http, $window, $route) {
if (
typeof $cookies.get('visitTrack') === 'undefined' ||
typeof $cookies.get('visitInfo') === 'undefined' ||
typeof $cookies.get('visitData') === 'undefined'
){
window.location.href = "#/";
return false;
}
$scope.visit = {};
$scope.visit.track = JSON.parse($cookies.get('visitTrack'));
$scope.visit.data = JSON.parse($cookies.get('visitData'));
$scope.visit.info = JSON.parse($cookies.get('visitInfo'));
$rootScope.preloader = true;
console.log('controller set');
});
template: function(elem,attrs) {
return '<select '+
'ng-model="'+attrs.model+'" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
}
在上面的模板中你有 ddlOpts
,我认为它是一个对象数组。当用户选择其中一个名称时,您在下拉列表中显示 name
并在 ng-model 中存储 option
。
对于 attrs.model
,您正在从 main 视图 model="visit.data.state_id"
传递数据。因此,您只传递一个 id
来设置默认选项。
如果你想设置一个默认选项,你必须传递一个匹配ddlOpts
的对象之一的对象。
另请注意,如果您尝试将对象传递给 model="visit.data.state_id"
,我认为您无法通过 attrs.model
读取指令内部的对象,因为 model=""
持有 string
.
您可能在指令中添加了一个独立的作用域绑定。
scope: {
popList: '=',
model: '='
},
在HTML
template: function(elem,attrs) {
return '<select '+
'ng-model="'+model+'" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
}
首先,感谢 Ravi,没有他我找不到答案...
好的,这是在指令中执行此操作的简明扼要。数据库正在发送一个只有一个键和一个整数值的对象。 Angular,当使用 ng-options 时,正在创建一个具有 k/v 对 id-int,name-string 的对象......正如你在我转换数据库数据时在这个 plunk 中看到的那样(MANUALLY ) 来匹配所选选项的结果,它就像一个魅力...
看这里:http://plnkr.co/edit/mlYKJQc7zQR0dsvDswMo
基本上,在尝试更改创建的指令的值时,只需确保 ng-model 中的数据对象与 ng-options 创建的数据对象相匹配...
或者如果您对提供的数据有同样的问题,您可以在设置 ddlOpts 之后写入一些内容,以根据从数据库发送的 int 进行设置,如下所示:
app.directive('popList', ['$http', function($http) {
'use strict';
var directive = {
restrict: 'EA',
scope: {
model: '='
},
template: function(elem,attrs) {
return '<select '+
'ng-model="model" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
},
link: link
};
return directive;
function link(scope, elem, attrs) {
var defaultInt;
if (typeof scope.model === "number"){
defaultInt = scope.model;
}else{
defaultInt = parseInt(scope.model);
}
var data = {
sTableName: attrs.tbl
};
$http.post('/emr4/ws/util.asmx/populateDDL',data).
then(function(response) {
scope.ddlOpts = response.data.d;
// THIS LINE BELOW HERE SETS THE VALUE POST COMPILE
angular.forEach(scope.ddlOpts, function (v, i) {
if (v.id === defaultInt) {
scope.model = v;
}
});
});
}
}]);
根据经验,最好让来自数据库的数据与 ANGULAR 创建的内容相匹配,但并非总是如此...
EDIT/UPDATE 我为这个问题添加了一个plunker: http://plnkr.co/edit/mlYKJQc7zQR0dsvDswMo
我正在将上一页的数据加载到我的页面控制器中的 $scope.visit 中。我想要一个指令,该指令使用数据库中的选项在页面上构造和加载 select 元素。这是我目前所拥有的:
app.directive('popList', ['$http', function($http) {
'use strict';
var directive = {
restrict: 'EA',
link: link,
scope: {
popList: '='
},
template: function(elem,attrs) {
return '<select '+
'ng-model="'+attrs.model+'" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
}
};
return directive;
function link(scope, elem, attrs, ctrl) {
var data = {
sTableName: attrs.tbl
};
$http.post('ddl.asmx/populateDDL',data).
then(function(response) {
console.log('This is the value I want to set it to '+scope.$parent.visit.data.state_id);
//ddlOpts loads with no problem
scope.ddlOpts = response.data.d;
});
}
}]);
然后 HTML 看起来像这样:
<div style="width: 5%" class="tableLabel">State</div>
<div
style="width: 27%;"
class="tableInput"
model="visit.data.state_id"
tbl="tblStates"
pop-list="states"
>
</div>
本质上,我传递了包含下拉选项的 table 的名称。我还传入了模型,它将告诉 select 默认值是什么(如果它有的话)
我可以毫无问题地将数据作为选项加载到 select 元素中。我已经检查了 ng-model 以确保我有正确的值来匹配 ng-value。我已经尝试过 ng-repeat,然后从头开始使用 ng-options,但我终生无法获得 select 选项来将默认值设置为 ng-model 值。
我开始认为这是因为 select 的构建范围与控制器将数据设置为 $scope.visit 的范围不同。有人可以解释为什么这两个范围不能相互识别,或者只是解释为什么我不能将我的默认值设置为存储在 ng-model 中的值吗?
这里是页面控制器,以备不时之需:
app.controller('demographicsFormCtrl', function($rootScope, $scope, $cookies, $http, $window, $route) {
if (
typeof $cookies.get('visitTrack') === 'undefined' ||
typeof $cookies.get('visitInfo') === 'undefined' ||
typeof $cookies.get('visitData') === 'undefined'
){
window.location.href = "#/";
return false;
}
$scope.visit = {};
$scope.visit.track = JSON.parse($cookies.get('visitTrack'));
$scope.visit.data = JSON.parse($cookies.get('visitData'));
$scope.visit.info = JSON.parse($cookies.get('visitInfo'));
$rootScope.preloader = true;
console.log('controller set');
});
template: function(elem,attrs) {
return '<select '+
'ng-model="'+attrs.model+'" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
}
在上面的模板中你有 ddlOpts
,我认为它是一个对象数组。当用户选择其中一个名称时,您在下拉列表中显示 name
并在 ng-model 中存储 option
。
对于 attrs.model
,您正在从 main 视图 model="visit.data.state_id"
传递数据。因此,您只传递一个 id
来设置默认选项。
如果你想设置一个默认选项,你必须传递一个匹配ddlOpts
的对象之一的对象。
另请注意,如果您尝试将对象传递给 model="visit.data.state_id"
,我认为您无法通过 attrs.model
读取指令内部的对象,因为 model=""
持有 string
.
您可能在指令中添加了一个独立的作用域绑定。
scope: {
popList: '=',
model: '='
},
在HTML
template: function(elem,attrs) {
return '<select '+
'ng-model="'+model+'" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
}
首先,感谢 Ravi,没有他我找不到答案...
好的,这是在指令中执行此操作的简明扼要。数据库正在发送一个只有一个键和一个整数值的对象。 Angular,当使用 ng-options 时,正在创建一个具有 k/v 对 id-int,name-string 的对象......正如你在我转换数据库数据时在这个 plunk 中看到的那样(MANUALLY ) 来匹配所选选项的结果,它就像一个魅力...
看这里:http://plnkr.co/edit/mlYKJQc7zQR0dsvDswMo
基本上,在尝试更改创建的指令的值时,只需确保 ng-model 中的数据对象与 ng-options 创建的数据对象相匹配...
或者如果您对提供的数据有同样的问题,您可以在设置 ddlOpts 之后写入一些内容,以根据从数据库发送的 int 进行设置,如下所示:
app.directive('popList', ['$http', function($http) {
'use strict';
var directive = {
restrict: 'EA',
scope: {
model: '='
},
template: function(elem,attrs) {
return '<select '+
'ng-model="model" '+
'ng-options="option.name for option in ddlOpts track by option.id" '+
'required '+
'></select>';
},
link: link
};
return directive;
function link(scope, elem, attrs) {
var defaultInt;
if (typeof scope.model === "number"){
defaultInt = scope.model;
}else{
defaultInt = parseInt(scope.model);
}
var data = {
sTableName: attrs.tbl
};
$http.post('/emr4/ws/util.asmx/populateDDL',data).
then(function(response) {
scope.ddlOpts = response.data.d;
// THIS LINE BELOW HERE SETS THE VALUE POST COMPILE
angular.forEach(scope.ddlOpts, function (v, i) {
if (v.id === defaultInt) {
scope.model = v;
}
});
});
}
}]);
根据经验,最好让来自数据库的数据与 ANGULAR 创建的内容相匹配,但并非总是如此...