自定义ngTagsInput& autoComplete指令(AngularJS) [英] Customizing ngTagsInput & autoComplete directives (AngularJS)
问题描述
我是AngularJS的新手,我目前正在开发一个输入字段,它可以同时接受多个标记以及自动完成功能,该功能会将可用标记显示为下拉选项。为此,我使用了我在网上找到的 ngTagsInput
指令( http://mbenford.github.io/ngTagsInput/ ),它为我提供了一个自定义HTML元素< tags-input>
。这非常有效:
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.jsintegrity =sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk =crossorigin =匿名>< / 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:
这是新的索引.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
,它包装< tags-input>
提供相同的功能,可以在< input>
标记内作为属性以及其他属性使用,例如 ng-model
, display-property
等所以我不必使用< tags-input>
元素直接。 问题是< 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>
或< span>
,包含在相同的< input tags-input-attr>
元素中。
or as an attribute inside a standard HTML element like <div>
or <span>
, wrapped inside the same <input tags-input-attr>
element.
如果不是以上两种,那么作为最后的手段,将< auto-complete>
标签包装在相同的<输入标签内 - input-attr>
元素
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指令进行了一些更改,现在它接受了所有类型的转换属性
到元素
指令。
I made some changes on the previus directive and now it accepts all kind of transformation from attribute
to element
directive.
你还有 elem-as-attr
属性,但现在你必须指定它的值
,它将是元素
将替换。
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>
您的应用程序JavaScript:
Your application JavaScript:
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;
};
});
指令代码:
The directive code:
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);
};
}
}
});
HTML代码:
元素方式:
HTML code:
Element way:
<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>
属性方式:
Attribute way:
<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>
Plunker:
请注意,
tagsInput
不能使用输入
元素,因为input
元素在HTML中没有结束标记。所以
你将无法在其中加入自动完成
元素。
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& autoComplete指令(AngularJS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!