如何在Angularjs指令动态NG-模型 [英] How to have dynamic ng-model in Angularjs directive
本文介绍了如何在Angularjs指令动态NG-模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想在同一个页面中使用多个指令。这些指令添加dynamically.may在同一页上我有2个指令或以上。如何添加NG-模型指令,当一个指令的变化值无法改变的其他指令。结果
该指令code源 https://github.com/JustGoscha/allmighty-autocomplete
\r
\r\r
\r VAR应用= angular.module('对myApp',[]);\r
app.directive(自动完成,函数(){\r
VAR数组1 = {[标题:苹果,值:1},{标题:索尼,值:2},{标题:LG,值:3}];\r
VAR数组2 = {[标题:Java的,值:1},{标题:C ++,值:2},{标题:C#,值:3}];\r
变种指数= -1;\r
返回{\r
限制:'E',\r
范围: {\r
网址:'@',\r
名称: '@',\r
searchParam:'= ngModel',\r
onType:'= onType',\r
ONSELECT:'= ONSELECT',\r
autocompleteRequired:'='\r
},\r
控制器:['$范围,$ HTTP',函数($范围,$ HTTP){\r
如果($ scope.url =='为url1)\r
$ scope.Items =数组1;\r
如果($ scope.url =='URL2')\r
$ scope.Items =数组2;\r
\r
$ scope.getItems =功能(){\r
返回scope.Items $;\r
}\r
//这是当前选择的建议索引\r
$ scope.selectedIndex = -1;\r
\r
$ scope.initLock =真;\r
\r
//设置新的索引\r
$ scope.setIndex =功能(我){\r
$ scope.selectedIndex = parseInt函数(I)\r
};\r
\r
this.setIndex =函数(ⅰ){\r
$ scope.setIndex(ⅰ);\r
$ $范围适用于()。\r
};\r
\r
$ scope.getIndex =功能(我){\r
返回$ scope.selectedIndex;\r
};\r
\r
//手表如果参数滤波器应该改变\r
VAR观看= TRUE;\r
\r
//自动填充下拉开/关\r
$ scope.completing = FALSE;\r
\r
//开始自动填充在打字的东西\r
$范围。$腕表('searchParam',功能(为newValue,属性oldValue){\r
\r
如果(属性oldValue ===为newValue ||(属性oldValue&安培;!&安培; $ scope.initLock)){\r
返回;\r
}\r
\r
如果(看&安培;&安培; typeof运算$ scope.searchParam =='不确定'和;!&安培;!$ scope.searchParam == NULL){\r
$ scope.completing = TRUE;\r
$ scope.searchFilter = $ scope.searchParam;\r
$ scope.selectedIndex = -1;\r
}\r
\r
//传递给上-type属性功能,这就是被执行\r
如果($ scope.onType)\r
$ scope.onType($ scope.searchParam);\r
});\r
\r
//为悬停建议\r
这一点。preSELECT =功能(建议){\r
\r
看着= FALSE;\r
\r
//这一行确定是否显示了它\r
//在输入字段之前,它的选择:\r
//$scope.searchParam =建议;\r
\r
$ $范围适用于()。\r
看着= TRUE;\r
\r
};\r
\r
。$范围preSELECT =此preSELECT。\r
\r
这一点。preSelectOff =功能(){\r
看着= TRUE;\r
};\r
\r
。$范围preSelectOff =此preSelectOff。\r
\r
//选择用右箭头或输入一个建议\r
$ scope.select =功能(建议,价值){\r
如果(建议){\r
$ scope.val =价值;\r
$ scope.searchParam =建议;\r
$ scope.searchFilter =建议;\r
如果($ scope.onSelect)\r
$ scope.onSelect(建议)\r
}\r
看着= FALSE;\r
$ scope.completing = FALSE;\r
的setTimeout(函数(){\r
看着= TRUE;\r
},1000);\r
$ scope.setIndex(-1);\r
};\r
\r
\r
}],\r
链接:功能(范围,元素,ATTRS){\r
\r
的setTimeout(函数(){\r
scope.initLock = FALSE;\r
。范围$适用();\r
},250);\r
\r
VAR ATTR ='';\r
\r
//默认的ATT\r
scope.attrs = {\r
占位符:开始输入...\r
阶级:,\r
ID: ,\r
inputclass:,\r
inputid:\r
};\r
\r
对(在ATTRS变种一个){\r
ATTR = a.replace('ATTR','').toLowerCase();\r
//添加属性覆盖默认值\r
//和preventing重复\r
如果(a.indexOf('ATTR')=== 0){\r
scope.attrs [ATTR] = ATTRS [A];\r
}\r
}\r
\r
如果(attrs.clickActivation){\r
元素[0] = .onclick功能(E){\r
如果(!scope.searchParam){\r
的setTimeout(函数(){\r
scope.completing = TRUE;\r
。范围$适用();\r
},200);\r
}\r
};\r
}\r
\r
VAR键= {左:37,最高:38,右:39,下降:40,请输入:13,ESC:27,标签:9};\r
\r
document.addEventListener(的keydown功能(E){\r
VAR键code = e.key code || e.which;\r
\r
开关(键code){\r
案例key.esc:\r
在逃生//禁用建议\r
scope.select();\r
scope.setIndex(-1);\r
。范围$适用();\r
亦即preventDefault();\r
}\r
},真正的);\r
\r
document.addEventListener(模糊,功能(E){\r
在模糊//禁用建议\r
//我们做一个超时prevent click事件被注册之前,隐藏它\r
的setTimeout(函数(){\r
scope.select();\r
scope.setIndex(-1);\r
。范围$适用();\r
},150);\r
},真正的);\r
\r
元素[0]阅读进度(的keydown功能(E){\r
VAR键code = e.key code || e.which;\r
\r
变种L = angular.element(本).find(礼)的长度。\r
\r
//这使得由pressing提交表单中输入的自动完成的领域\r
如果(!scope.completing ||升== 0)回报;\r
\r
//执行上下建议列表中移动\r
开关(键code){\r
案例key.up:\r
\r
指数= scope.getIndex() - 1;\r
如果(指数< -1){\r
指数= L - 1;\r
}否则如果(索引> = 1){\r
指数= -1;\r
scope.setIndex(索引);\r
范围preSelectOff();\r
打破;\r
}\r
scope.setIndex(索引);\r
\r
如果(指数!== -1)\r
范围preSELECT(angular.element(angular.element(本).find(礼)[指数])文本());\r
\r
。范围$适用();\r
\r
打破;\r
案例key.down:\r
指数= scope.getIndex()+ 1;\r
如果(指数< -1){\r
指数= L - 1;\r
}否则如果(索引> = 1){\r
指数= -1;\r
scope.setIndex(索引);\r
范围preSelectOff();\r
。范围$适用();\r
打破;\r
}\r
scope.setIndex(索引);\r
\r
如果(指数!== -1)\r
范围preSELECT(angular.element(angular.element(本).find(礼)[指数])文本());\r
\r
打破;\r
案例key.left:\r
打破;\r
案例key.right:\r
案例key.enter:\r
案例key.tab:\r
\r
指数= scope.getIndex();\r
//范围preSelectOff();\r
如果(指数!== -1){\r
scope.select(angular.element(angular.element(本).find(礼)[指数])。文本()\r
angular.element(angular.element(本).find(礼)[指数])[0] .ID);\r
如果(键code == key.enter){\r
亦即preventDefault();\r
}\r
}其他{\r
如果(键code == key.enter){\r
scope.select();\r
}\r
}\r
scope.setIndex(-1);\r
。范围$适用();\r
\r
打破;\r
案例key.esc:\r
在逃生//禁用建议\r
scope.select();\r
scope.setIndex(-1);\r
。范围$适用();\r
亦即preventDefault();\r
打破;\r
默认:\r
返回;\r
}\r
\r
});\r
},\r
模板:'\\\r
< DIV CLASS =自动完成{{attrs.class}}ID ={{attrs.id}}> \\\r
<输入\\\r
TYPE =文本\\\r
NG-模式=searchParam\\\r
占位={{attrs.placeholder}}\\\r
类={{attrs.inputclass}}\\\r
编号={{attrs.inputid}}\\\r
NG-所需={{autocompleteRequired}}/> \\\r
<输入\\\r
类型=隐藏\\\r
NAME ={{名}}NG值={{VAL}}\\\r
/> \\\r
< UL NG秀=完成&放大器;及(项目|过滤器:searchFilter)。长度大于0> \\\r
<李\\\r
\\\r
NG-重复=,在项目项目|过滤器:searchFilter |排序依据:\\'的toString()\\'由$指数跟踪\\\r
指数={{$指数}}\\\r
编号={{item.value}}\\\r
VAL ={{item.title}}\\\r
NG-CLASS ={活跃:($指数===的selectedIndex)}\\\r
NG-点击=SELECT(item.title,item.value)\\\r
NG-绑定-HTML =item.title |亮点:searchParam> \\\r
< /李> \\\r
< / UL> \\\r
< / DIV>'\r
};\r
});\r
\r
app.filter('亮点',['$ SCE',函数($ SCE){\r
返回功能(输入,searchParam){\r
如果(typeof运算输入==='功能')返回'';\r
如果(searchParam){\r
VAR字='('+\r
。searchParam.split(/ \\ /)加入('|')+'|' +\r
。searchParam.split(/ \\ /)加入('|')+\r
')',\r
EXP =新的RegExp(话说,GI);\r
如果(words.length){\r
输入= input.replace(EXP,<跨度类= \\亮点\\> $ 1 LT; / SPAN>);\r
}\r
}\r
返回$ sce.trustAsHtml(输入);\r
};\r
}]);\r
\r
app.directive('建议',函数(){\r
返回{\r
限制:'A',\r
要求:'^自动完成',// ^找家长控制元素\r
链接:功能(范围,元素,ATTRS,autoCtrl){\r
element.bind('的mouseenter',函数(){\r
autoCtrl preSELECT(attrs.val)。\r
autoCtrl.setIndex(attrs.index);\r
});\r
\r
element.bind('鼠标离开',函数(){\r
autoCtrl preSelectOff()。\r
});\r
}\r
};\r
});
\r
/ * * AUTOCOMPLETE /\r
\r
.autocomplete {\r
宽度:100%;\r
位置:相对;\r
}\r
\r
.autocomplete输入{\r
字体大小:1.2em;\r
宽度:100%;\r
填充:0.4em;\r
}\r
\r
.autocomplete UL {\r
位置:绝对的;\r
左:0;\r
宽度:100%;\r
左边框:1px的固体#888;\r
右边框:1px的固体#888;\r
下边框:1px的固体#888;\r
的z-index:1;\r
}\r
\r
.autocomplete李{\r
文本对齐:左;\r
列表样式:无;\r
宽度:100%;\r
填充:0.4em;\r
背景色:#FFF;\r
}\r
\r
.autocomplete li.active {\r
宽度:100%;\r
背景颜色:#4BF;\r
}\r
\r
.autocomplete .highlight {\r
背景颜色:#E2E2E2;\r
}\r
\r
.autocomplete li.active .highlight {\r
背景:#666;\r
颜色:#FFF;\r
}
\r
&LT;脚本SRC =https://ajax.googleapis.com/ajax /libs/angularjs/1.2.23/angular.min.js\"></script>\r
&LT; DIV NG-应用=对myApp&GT;\r
&LT;自动完成URL =为url1NG模型=结果attr-\r
点击激活=真\r
在-TYPE =DoSomething的关于选=doSomethingElse&GT;&LT; /自动完成&GT;\r
&LT;自动完成URL =URL2NG模型=结果attr-\r
点击激活=真\r
在-TYPE =DoSomething的关于选=doSomethingElse&GT;&LT; /自动完成&GT;\r
&LT; / DIV&GT;
\r
解决方案
您可以用数组变量尝试为NG-模式,
$ scope.result = [];
然后用它作为
NG-模型=的结果[$指数]//如果你正在使用NG-重复
或
NG-模型=的结果[0]
NG-模型=的结果[1]// ..这样的
i want to use multiple directive in same page. these directive add dynamically.may be in same page i have 2 directive or more. how to add ng-model to directive that when changes value of one directive not change other directive.
this directive code source is https://github.com/JustGoscha/allmighty-autocomplete
var app = angular.module('myApp', []);
app.directive('autocomplete', function () {
var array1 =[ {title:"apple", value:1},{title:"sony", value:2},{title:"LG", value:3}];
var array2 = [{title:"java", value:1},{title:"c++", value:2},{title:"c#", value:3}];
var index = -1;
return {
restrict: 'E',
scope: {
url: '@',
name: '@',
searchParam: '=ngModel',
onType: '=onType',
onSelect: '=onSelect',
autocompleteRequired: '='
},
controller: ['$scope', '$http', function ($scope, $http) {
if($scope.url == 'url1')
$scope.Items = array1;
if($scope.url == 'url2')
$scope.Items = array2;
$scope.getItems = function () {
return $scope.Items;
}
// the index of the suggestions that's currently selected
$scope.selectedIndex = -1;
$scope.initLock = true;
// set new index
$scope.setIndex = function (i) {
$scope.selectedIndex = parseInt(i);
};
this.setIndex = function (i) {
$scope.setIndex(i);
$scope.$apply();
};
$scope.getIndex = function (i) {
return $scope.selectedIndex;
};
// watches if the parameter filter should be changed
var watching = true;
// autocompleting drop down on/off
$scope.completing = false;
// starts autocompleting on typing in something
$scope.$watch('searchParam', function (newValue, oldValue) {
if (oldValue === newValue || (!oldValue && $scope.initLock)) {
return;
}
if (watching && typeof $scope.searchParam !== 'undefined' && $scope.searchParam !== null) {
$scope.completing = true;
$scope.searchFilter = $scope.searchParam;
$scope.selectedIndex = -1;
}
// function thats passed to on-type attribute gets executed
if ($scope.onType)
$scope.onType($scope.searchParam);
});
// for hovering over suggestions
this.preSelect = function (suggestion) {
watching = false;
// this line determines if it is shown
// in the input field before it's selected:
//$scope.searchParam = suggestion;
$scope.$apply();
watching = true;
};
$scope.preSelect = this.preSelect;
this.preSelectOff = function () {
watching = true;
};
$scope.preSelectOff = this.preSelectOff;
// selecting a suggestion with RIGHT ARROW or ENTER
$scope.select = function (suggestion, value) {
if (suggestion) {
$scope.val = value;
$scope.searchParam = suggestion;
$scope.searchFilter = suggestion;
if ($scope.onSelect)
$scope.onSelect(suggestion);
}
watching = false;
$scope.completing = false;
setTimeout(function () {
watching = true;
}, 1000);
$scope.setIndex(-1);
};
}],
link: function (scope, element, attrs) {
setTimeout(function () {
scope.initLock = false;
scope.$apply();
}, 250);
var attr = '';
// Default atts
scope.attrs = {
"placeholder": "start typing...",
"class": "",
"id": "",
"inputclass": "",
"inputid": ""
};
for (var a in attrs) {
attr = a.replace('attr', '').toLowerCase();
// add attribute overriding defaults
// and preventing duplication
if (a.indexOf('attr') === 0) {
scope.attrs[attr] = attrs[a];
}
}
if (attrs.clickActivation) {
element[0].onclick = function (e) {
if (!scope.searchParam) {
setTimeout(function () {
scope.completing = true;
scope.$apply();
}, 200);
}
};
}
var key = {left: 37, up: 38, right: 39, down: 40, enter: 13, esc: 27, tab: 9};
document.addEventListener("keydown", function (e) {
var keycode = e.keyCode || e.which;
switch (keycode) {
case key.esc:
// disable suggestions on escape
scope.select();
scope.setIndex(-1);
scope.$apply();
e.preventDefault();
}
}, true);
document.addEventListener("blur", function (e) {
// disable suggestions on blur
// we do a timeout to prevent hiding it before a click event is registered
setTimeout(function () {
scope.select();
scope.setIndex(-1);
scope.$apply();
}, 150);
}, true);
element[0].addEventListener("keydown", function (e) {
var keycode = e.keyCode || e.which;
var l = angular.element(this).find('li').length;
// this allows submitting forms by pressing Enter in the autocompleted field
if (!scope.completing || l == 0) return;
// implementation of the up and down movement in the list of suggestions
switch (keycode) {
case key.up:
index = scope.getIndex() - 1;
if (index < -1) {
index = l - 1;
} else if (index >= l) {
index = -1;
scope.setIndex(index);
scope.preSelectOff();
break;
}
scope.setIndex(index);
if (index !== -1)
scope.preSelect(angular.element(angular.element(this).find('li')[index]).text());
scope.$apply();
break;
case key.down:
index = scope.getIndex() + 1;
if (index < -1) {
index = l - 1;
} else if (index >= l) {
index = -1;
scope.setIndex(index);
scope.preSelectOff();
scope.$apply();
break;
}
scope.setIndex(index);
if (index !== -1)
scope.preSelect(angular.element(angular.element(this).find('li')[index]).text());
break;
case key.left:
break;
case key.right:
case key.enter:
case key.tab:
index = scope.getIndex();
// scope.preSelectOff();
if (index !== -1) {
scope.select(angular.element(angular.element(this).find('li')[index]).text(),
angular.element(angular.element(this).find('li')[index])[0].id);
if (keycode == key.enter) {
e.preventDefault();
}
} else {
if (keycode == key.enter) {
scope.select();
}
}
scope.setIndex(-1);
scope.$apply();
break;
case key.esc:
// disable suggestions on escape
scope.select();
scope.setIndex(-1);
scope.$apply();
e.preventDefault();
break;
default:
return;
}
});
},
template: '\
<div class="autocomplete {{ attrs.class }}" id="{{ attrs.id }}">\
<input\
type="text"\
ng-model="searchParam"\
placeholder="{{ attrs.placeholder }}"\
class="{{ attrs.inputclass }}"\
id="{{ attrs.inputid }}"\
ng-required="{{ autocompleteRequired }}" />\
<input\
type="hidden"\
name="{{name}}" ng-value="{{ val }}"\
/>\
<ul ng-show="completing && (Items | filter:searchFilter).length > 0">\
<li\
\
ng-repeat="item in Items | filter:searchFilter | orderBy:\'toString()\' track by $index"\
index="{{ $index }}"\
id="{{item.value}}"\
val="{{ item.title }}"\
ng-class="{ active: ($index === selectedIndex) }"\
ng-click="select(item.title,item.value)"\
ng-bind-html="item.title | highlight:searchParam">\
</li>\
</ul>\
</div>'
};
});
app.filter('highlight', ['$sce', function ($sce) {
return function (input, searchParam) {
if (typeof input === 'function') return '';
if (searchParam) {
var words = '(' +
searchParam.split(/\ /).join(' |') + '|' +
searchParam.split(/\ /).join('|') +
')',
exp = new RegExp(words, 'gi');
if (words.length) {
input = input.replace(exp, "<span class=\"highlight\">$1</span>");
}
}
return $sce.trustAsHtml(input);
};
}]);
app.directive('suggestion', function () {
return {
restrict: 'A',
require: '^autocomplete', // ^look for controller on parents element
link: function (scope, element, attrs, autoCtrl) {
element.bind('mouseenter', function () {
autoCtrl.preSelect(attrs.val);
autoCtrl.setIndex(attrs.index);
});
element.bind('mouseleave', function () {
autoCtrl.preSelectOff();
});
}
};
});
/* AUTOCOMPLETE */
.autocomplete {
width: 100%;
position: relative;
}
.autocomplete input {
font-size: 1.2em;
width: 100%;
padding: 0.4em;
}
.autocomplete ul {
position: absolute;
left: 0;
width: 100%;
border-left: 1px solid #888;
border-right: 1px solid #888;
border-bottom: 1px solid #888;
z-index: 1;
}
.autocomplete li {
text-align: left;
list-style: none;
width: 100%;
padding: 0.4em;
background-color: #fff;
}
.autocomplete li.active {
width: 100%;
background-color: #4bf;
}
.autocomplete .highlight {
background-color: #E2E2E2;
}
.autocomplete li.active .highlight {
background: #666;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<autocomplete url="url1" ng-model="result" attr-
click-activation="true"
on-type="doSomething" on-select="doSomethingElse"></autocomplete>
<autocomplete url="url2" ng-model="result" attr-
click-activation="true"
on-type="doSomething" on-select="doSomethingElse"></autocomplete>
</div>
解决方案
you could try with array variable as the ng-model,
$scope.result = [];
then use it as
ng-model="result[$index]" //if you are using ng-repeat
or
ng-model="result[0]"
ng-model="result[1]" //.. like this
这篇关于如何在Angularjs指令动态NG-模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文