Customizing ngTagsInput amp; autoComplete directives (AngularJS)(自定义 ngTagsInput amp;自动完成指令(AngularJS))
问题描述
我是 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>
您的应用程序 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;
};
});
指令代码:
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 代码:
元素方式:
<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>
Plunker:
https://plnkr.co/edit/9TqsXy
请注意,您不能将 input 元素用于 tagsInput因为 input 元素在 HTML 中没有结束标记.所以您将无法将 auto-complete 元素放入其中.
Note that you cannot use the
inputelement for thetagsInputbecause theinputelement does not have the closing tag in HTML. So you will not be able to put theauto-completeelement inside it.
这篇关于自定义 ngTagsInput &自动完成指令(AngularJS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:自定义 ngTagsInput &自动完成指令(AngularJS)
基础教程推荐
- 什么是不使用 jQuery 的经验技术原因? 2022-01-01
- WatchKit 支持 html 吗?有没有像 UIWebview 这样的控制器? 2022-01-01
- 如何使用 CSS 显示和隐藏 div? 2022-01-01
- 每次设置弹出窗口的焦点 2022-01-01
- Javascript 在多个元素上单击事件侦听器并获取目标 2022-01-01
- Node.js 有没有好的索引/搜索引擎? 2022-01-01
- 如何在特定日期之前获取消息? 2022-01-01
- jQuery File Upload - 如何识别所有文件何时上传 2022-01-01
- 如何使用sencha Touch2在单页中显示列表和其他标签 2022-01-01
- 为什么我在 Vue.js 中得到 ERR_CONNECTION_TIMED_OUT? 2022-01-01
