我是AngularJS的新手,目前正在处理一个输入字段,该字段可以一次接受多个标签以及自动完成功能,该功能将可用标签显示为下拉选项。为此,我使用在ngTagsInputWeb上找到的指令(http://mbenford.github.io/ngTagsInput/),该指令为我提供了一个自定义HTML元素<tags- input>。这很漂亮:
ngTagsInput
<tags- input>
index.html:
index.html
<script> var app = angular.module('plunker', ['ngTagsInput']); app.controller('MainCtrl', function($scope, $http) { $scope.tags = [ { text: 'Tag1' }, { text: 'Tag2' }, { text: 'Tag3' } ]; $scope.loadTags = function(query) { return $http.get('tags.json'); }; }); </script> <div ng-app="plunker" ng-controller="MainCtrl"> <tags-input ng-model="tags" add-on-paste="true" display-property="text" placeholder="Add a Tag" add-from-autocomplete-only="true"> <auto-complete max-results-to-show="4" min-length="2" source="loadTags($query)"></auto-complete> </tags-input> </div>
tags.json:
tags.json
[ { "text": "Tag1" }, { "text": "Tag2" }, { "text": "Tag3" }, { "text": "Tag4" }, { "text": "Tag5" }, { "text": "Tag6" }, { "text": "Tag7" }, { "text": "Tag8" }, { "text": "Tag9" }, { "text": "Tag10" } ]
但是,我想使用标准HTML <input>元素而不是<tags-input>指令附带的自定义元素,因此,在很多帮助和使用下,<script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"></script>我可以在此处进行操作:
<input>
<tags-input>
<script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"></script>
这是新的index.html:
<script> var app = angular.module('plunker', ['ngTagsInput']); app.controller('MainCtrl', function($scope, $http) { $scope.tags = [ { "id":1, "tagname": 'Tag1' }, { "id":2, "tagname": 'Tag2' }, { "id":3, "tagname": 'Tag3' }, { "id":4, "tagname": 'Tag4' } ]; $scope.loadTags = function(query) { return $http.get('tags.json'); }; }); app.directive('tagsInputAttr', function($compile){ return { restrict: 'A', require: '?ngModel', scope:{ ngModel: '=' }, link: function($scope, element, attrs, controller) { var attrsText = ''; $.each($(element)[0].attributes, function(idx, attr) { if (attr.nodeName === "tags-input-attr" || attr.nodeName === "ng-model") return; attrsText += " " + attr.nodeName + "='" + attr.nodeValue + "'"; }); var html ='<tags-input ng-model="ngModel" ' + attrsText + '></tags-input>'; e =$compile(html)($scope); $(element).replaceWith(e); } }; } ); </script> <div ng-app="plunker" ng-controller="MainCtrl"> <input tags-input-attr ng-model="tags" add-on-paste="true" display-property="tagname" placeholder="Add tags here..." add-from-autocomplete-only="true"> <auto-complete max-results-to-show="3" min-length="2" source="loadTags($query)"></auto-complete> </input> </div>
和新的tags.json:
[ { "id":1, "tagname": "Tag1" }, { "id":2, "tagname": "Tag2" }, { "id":3, "tagname": "Tag3" }, { "id":4, "tagname": "Tag4" }, { "id":5, "tagname": "Tag5" }, { "id":6, "tagname": "Tag6" }, { "id":7, "tagname": "Tag7" }, { "id":8, "tagname": "Tag8" }, { "id":9, "tagname": "Tag9" }, { "id":10, "tagname": "Tag10" } ]
如您所见tagsInputAttr,包装了的new指令<tags- input>提供了相同的功能,并且可以在<input>标记中与其他属性(例如ng-model,display- property等)一起用作属性使用,因此我不必<tags-input>直接使用该元素。该 问题 是,<auto- complete>放在里面<input>的标签不起作用。
tagsInputAttr
ng-model
display- property
<auto- complete>
为此,我需要考虑以下因素来更改我的指令:
注意: 我不想为此使用jquery
我的问题是如何包装<auto-complete>相同的<input tags-input-attr>元素:
<auto-complete>
<input tags-input-attr>
作为同一<input tags-input-attr>元素内的一个属性
或作为包装在同一元素内的标准HTML元素(如<div>或)内的属性。<span>``<input tags-input-attr>
<div>
<span>``<input tags-input-attr>
如果不是以上两个,则作为最后的选择,将<auto-complete>标签包裹在同一<input tags-input-attr>元素内
感谢所有帮助。提前致谢。
我对previus指令进行了一些更改,现在它接受从attribute到element指令的所有转换。
attribute
element
您仍然具有该elem-as-attr属性,但是现在您必须指定该属性,value它将被element替换。
elem-as-attr
value
例:
<div elem-as-attr="tags-input"></div>
var app = angular.module('plunker', ['ngTagsInput']); app.controller('MainCtrl', function($scope, $http) { $scope.allTags = [ { "id":1, "tagname": "Tag1" }, { "id":2, "tagname": "Tag2" }, { "id":3, "tagname": "Tag3" }, { "id":4, "tagname": "Tag4" }, { "id":5, "tagname": "Tag5" }, { "id":6, "tagname": "Tag6" }, { "id":7, "tagname": "Tag7" }, { "id":8, "tagname": "Tag8" }, { "id":9, "tagname": "Tag9" }, { "id":10, "tagname": "Tag10" } ]; $scope.myTags =[ $scope.allTags[2], $scope.allTags[4], $scope.allTags[8] ]; $scope.loadTags = function(query) { return $scope.allTags; }; });
app.directive('elemAsAttr', function($compile) { return { restrict: 'A', require: '?ngModel', replace: true, scope: true, compile: function(tElement, tAttrs) { return function($scope) { var attrs = tElement[0].attributes; var attrsText = ''; for (var i=0; i < attrs.length; i++) { var attr = attrs.item(i); if (attr.nodeName === "elem-as-attr") { continue; } attrsText += " " + attr.nodeName + "='" + attr.nodeValue + "'"; } var hasModel = $(tElement)[0].hasAttribute("ng-model"); var innerHtml = $(tElement)[0].innerHTML; var html = '<' + tAttrs.elemAsAttr + attrsText + '>' + innerHtml + '</' + tAttrs.elemAsAttr + '>'; var e = hasModel ? $compile(html)($scope) : html; $(tElement).replaceWith(e); }; } } });
<tags-input ng-model="myTags" add-on-paste="true" display-property="tagname" placeholder="Add a Tag" add-from-autocomplete-only="true"> <auto-complete max-results-to-show="10" display-property="tagname" min-length="2" source="loadTags($query)"></auto-complete> </tags-input>
<div elem-as-attr="tags-input" ng-model="myTags" add-on-paste="true" display-property="tagname" placeholder="Add tags here..." add-from-autocomplete-only="true"> <div elem-as-attr="auto-complete" max-results-to-show="10" display-property="tagname" min-length="2" source="loadTags($query)"></div> </div>
https://plnkr.co/edit/9TqsXy
请注意,您不能将input元素用于,tagsInput 因为该input元素在HTML中没有结束标记。因此,您将无法将auto- complete元素放入其中。
input
tagsInput
auto- complete