我想要完成的是创建一个能够使用数组或对象模型生成选择下拉列表的指令。我从服务器获取一组对象,我想要生成仅使用“user_id”来显示我的选项的模板。这是我尝试过的:
HTML
<ng-select options="error.currentOrder.loggedPackages" selected="error.selected.user" object-field="user_id"></ng-select>
模板
<div class="select dropdown">
<button data-toggle="dropdown"><% selected %><i class="fa fa-angle-down"></i></button>
<ul ng-if="!objectField" class="dropdown-menu">
<li ng-repeat="option in options" ng-click="selectOption($index)"><% option %></li>
</ul>
<ul ng-if="objectField" class="dropdown-menu">
<li ng-repeat="option in options" ng-click="selectOption($index)"><% option[objectField] %></li>
</ul>
</div>
Javascript
Application.directive('ngSelect', function () {
return {
restrict : 'E',
replace : true,
templateUrl : '/templates/directives/select.html',
scope : {
options: '=',
selected: '=',
objectField: '='
},
controller : ['$scope', function ($scope) {
$scope.selectOption = function (index) {
$scope.selected = $scope.options[index];
}
}],
link: function(scope, elem, attrs)
{
console.log(scope.objectField);
console.log('seleeeect');
}
}
});
Application.controller('ErrorReportingController', ['$scope', '$http', 'initData', 'ServerActions', function($scope, $http, initData, ServerActions) {
var error = this;
error.initData = initData;
error.selected = {
}
error.submitOrder = function (orderID) {
ServerActions.fetchData('/packing/error.action', {id : orderID}).then(
function (response) {
console.log(response.data);
error.currentOrder = response.data;
}
)
};
console.log(error.initData);
}]);
最佳答案
所以,如果我理解正确的话,您需要带有动态模板的指令,这取决于 options
的类型和 object-field
属性的存在。另外,如果 object-field
是嵌套的,那就会很棘手:)
这是我解决这个问题的方法:
HTML
<html ng-app="app">
<head>
<link data-require="font-awesome@*" data-semver="4.3.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
<script data-require="angular.js@1.4.6" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="appCtrl">
<h3>Array of Strings: {{selectedString}}</h3>
<app-select
options="stringModel"
selected="selectedString"
></app-select>
<h3>Array of Objects: {{selectedObject}}</h3>
<app-select
options="objectModel"
selected="selectedObject"
object-field="some.nested.field"
></app-select>
</body>
</html>
JavaScript
angular.module('app',[]).
controller('appCtrl', ['$scope', function($scope) {
$scope.stringModel = ["First", "Second", "Third"];
$scope.objectModel = [{some: {nested: {field: "First"}}}, {some: {nested: {field: "Second"}}}, {some: {nested: {field: "Third"}}}];
$scope.selectedString = $scope.stringModel[1];
$scope.selectedObject = $scope.objectModel[2];
}]).
directive('appSelect', ['$compile', function($compile) {
return {
scope: {
'options': '=',
'selected': '='
},
controllerAs: 'vm',
bindToController: true,
controller: [function() {
this.visible = false;
this.selectItem = function($index) {
this.selected = this.options[$index];
this.visible = false;
};
}],
compile: function(template, attrs) {
var isObject = !!attrs['objectField'],
html = '<div class="select dropdown">' +
'<button data-toggle="dropdown">' +
'{{vm.' + (isObject ? 'selected.' + attrs.objectField : 'selected') + '}}' +
'<i class="fa fa-angle-down" ng-click="vm.visible=!vm.visible"></i>' +
'</button>' +
'<ul class="dropdown-menu" ng-if="vm.visible">' +
'<li ng-repeat="option in vm.options track by $index" ng-click="vm.selectItem($index)">' +
'{{' + (isObject ? 'option.' + attrs.objectField : 'option') + '}}' +
'</li>' +
'</ul>' +
'</div>';
return function postLink(scope, el) {
el.html(html);
$compile(el.contents())(scope);
};
}
}
}]);
如果您需要通过URL加载模板,也是可以的。由于编译函数是在模板加载后调用的,因此您可以在编译函数中用其他内容替换一些占位符,例如“{{selected}}”和“{{option}}”:
...
templateUrl: 'template.html',
compile: function(template, attrs) {
var isObject = !!attrs['objectField'],
selected = isObject ? 'selected.' + attrs.objectField : 'selected',
option = isObject ? 'option.' + attrs.objectField : 'option';
html = template.html().
replace('{{selected}}', '{{vm.' + selected + '}}').
replace('{{option}}', '{{' + option + '}}');
return function postLink(scope, el) {
el.html(html);
$compile(el.contents())(scope);
};
}
...
template.html
<div class="select dropdown">
<button data-toggle="dropdown">
{{selected}}<i class="fa fa-angle-down" ng-click="vm.visible=!vm.visible"></i>
</button>
<ul class="dropdown-menu" ng-if="vm.visible">
<li ng-repeat="option in vm.options track by $index" ng-click="vm.selectItem($index)">{{option}}</li>
</ul>
</div>
笨蛋
- 静态模板:http://plnkr.co/edit/DSOCHqKDFauxCVOEMNA9?p=preview
- 通过 URL 加载模板:http://plnkr.co/edit/zLkpUxQCGNkZIyFb0vC5?p=preview
您可以在此处查看有关动态模板的更多信息:
关于javascript - Angular 指令 - 选择下拉数组或对象模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32904965/