我有一个下拉框,显示一些任意键值对。问题是在范围内只有密钥驻留,并且必须翻译到相应的密钥值对中。
到目前为止,我有一个非常(至少对我来说)好看的解决方案,你可以在这里检查JSFiddle。
在我的HTML代码中,我想写下这样的内容:
<div data-ng-app="myApp" ng-strict-di>
<div data-ng-controller="myController">
<select as-relative-ranking data-ng-model="myRating">
</select>
</div>
</div>
我的控制代码看起来像这样:
app.controller('myController', ['$scope', function($scope) {
$scope.myRating = 2;
}]);
为了获得键值对之间的链接,我编写了以下指令:
app.directive('asRelativeRanking', [function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
var relativeRatingOptions = [{
description: 'Good',
value: 1
}, {
description: 'Better',
value: 2
}];
scope._asRelativeRatingOptions = relativeRatingOptions;
// ToDo: Set the data-ng-options value a way that lets angular really use it.
element.attr('data-ng-options', 'relativeRating.description for relativeRating in _asRelativeRatingOptions track by relativeRating.value');
// format text going to view (model to view)
ngModel.$formatters.push(function(value) {
return value == null ? value : relativeRatingOptions.filter(function(relativeRating) {
return relativeRating.value === value;
})[0];
});
// format text from view (view to model)
ngModel.$parsers.push(function(option) {
return option == null ? option : option.value;
});
}
}
}]);
不幸的是设置element.attr
不起作用,所以角度尊重它。在DOM中我可以看到语句,但angular不会处理它。如果我将HTML重写为:
<select as-relative-ranking
data-ng-model="myRating"
data-ng-options='relativeRating.description for relativeRating in _asRelativeRatingOptions track by relativeRating.value'>
</select>
一切正常,但我想从指令中更改ngOptions,以便我的HTML保持干净。
答案 0 :(得分:0)
<强> HTML 强>
<div ng-controller="Ctrl">
<div>
<h2>Without directive</h2>
<label>Ferries</label>
<select ng-model="ferry" ng-options="ferry.Id as ferry.Description for ferry in ferries">
<option style="display: none" value="">-- Choose ferry --</option>
</select>
<br/>
<label>Routes</label>
<select ng-model="route" ng-options="route.Code as route.Name for route in routes">
<option style="display: none" value="">-- Choose route --</option>
</select>
</div>
<div>
<h2>With directive (working now!)</h2>
<dropdown title="Choose ferry" label="Ferries" array="ferries" opt-value="Id" opt-description="Description"></dropdown>
<dropdown title="Choose route" label="Routes" array="routes" opt-value="Code" opt-description="Name"></dropdown>
</div>
<强> app.js 强>
var app = angular.module('app', []);
function Ctrl($scope){
$scope.ferries = [
{Id: 1, Description: "ferry1"},
{Id: 2, Description:"ferry2"},
{Id: 3, Description: "ferry3"}
];
$scope.routes = [
{Code: "RT1", Name: "route1"},
{Code: "RT2", Name:"route2"},
{Code: "RT2", Name: "route3"}
];
}
app.directive('dropdown', function(){
return {
restrict: 'E',
scope: {
array: '='
},
template: '<label>{{label}}</label>' +
'<select ng-model="ngModel" ng-options="a[optValue] as a[optDescription] for a in array">' +
'<option style="display: none" value="">-- {{title}} --</option>' +
'</select>',
link: function (scope, element, attrs) {
scope.label = attrs.label;
scope.title = attrs.title;
scope.optValue = attrs.optValue;
scope.optDescription = attrs.optDescription;
}
};
});
demo click here