我是 AngularJS 的新手,目前正在处理一个输入字段,它可以一次接受多个标签以及自动完成功能,它将可用标签显示为下拉选项.为此,我使用了我在网上找到的 ngTagsInput
指令(http://mbenford.github.io/ngTagsInput/),它为我提供了一个自定义 HTML 元素
.这很好用:
I am new to AngularJS and am currently working on an input field, which can accept multiple tags at a time along with the auto-complete feature, which display the available tags as dropdown options. For this I am using the ngTagsInput
directive I found on the web(http://mbenford.github.io/ngTagsInput/), which gives me a custom HTML element <tags-input>
. This works beautifully:
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
:
[
{ "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>
我可以在这里做到:
However I wanted to use the standard HTML <input>
element instead of the custom <tags-input>
element which comes along with the directive, so with a lot of help and using <script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"></script>
I was able to do it here:
这是新的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
包装了
提供了相同的功能,并且可以在 中使用.input>
标记作为一个属性以及其他属性,例如 ng-model
、display-property
等.所以我不必使用
元素直接.问题是 <auto-complete>
放置在 <input>
标记内不起作用.
As you can notice,the new directive tagsInputAttr
, which wraps the <tags-input>
provides the same functionality and can be used inside <input>
tag as an attribute along with the rest of attributes such as ng-model
, display-property
etc. So I don't have to use the <tags-input>
element directly. The problem is that the <auto-complete>
placed inside the <input>
tag doesn't work.
为此,我需要修改我的指令,考虑以下几点:
For this I need to alter my directive, considering the following:
注意:我不想为此使用 jquery
Note: I do not want to use jquery for this
我的问题是如何将 <auto-complete>
包装在同一个 <input tags-input-attr>
元素中:
My question is how do I wrap the <auto-complete>
inside the same <input tags-input-attr>
element:
作为同一<input tags-input-attr>
元素内的属性
或作为标准 HTML 元素内的属性,如 <div>
或 ,包裹在相同的
元素.
or as an attribute inside a standard HTML element like <div>
or <span>
, wrapped inside the same <input tags-input-attr>
element.
如果不是以上两个,那么作为最后的手段,将<auto-complete>
标签包裹在同一个 元素
If not the above two, then as last resort, as the <auto-complete>
tag wrapped inside the same <input tags-input-attr>
element
感谢所有帮助.提前致谢.
All help is appreciated. Thanks in advance.
我对previus指令做了一些修改,现在它接受了从attribute
到element
指令.
I made some changes on the previus directive and now it accepts all kind of transformation from attribute
to element
directive.
你仍然有 elem-as-attr
属性,但现在你必须指定它的 value
,它将是 element代码>将替换.
You still have the elem-as-attr
attribute, but now you have to specify the value
of it, that it will be the element
that will replace.
例子:
<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
元素放入其中.
Note that you cannot use the
input
element for thetagsInput
because theinput
element does not have the closing tag in HTML. So you will not be able to put theauto-complete
element inside it.
这篇关于自定义 ngTagsInput &自动完成指令(AngularJS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!