这个错误是什么"[$compile:nonassign]"在angularjs指令中
What is this error "[$compile:nonassign]" in angularjs directive
我正在写一个指令,并在控制台中得到以下内容:
错误:[$compile:nonassign] http://errors.angularjs.org/1.3.14/$compile/nonassign?p0=undefined&p1=autocomplete
实际上我想在模板中有一个动态模型。模板中的输入元素有动态模型名。
<input'
type="text"
ng-model="modelName"' />
具有动态模型名称,我正在创建一个标记并传递路径作为模型名称。
<s:bind path="${path}">
<autocomplete url="${url}" name="${path}" model-name="${path}"
click-activation="true"
on-type="doSomething" on-select="doSomethingElse"> </autocomplete>
</s:bind>
和$scope。手表我正在看所有型号的名字。
$scope.$watch($scope.modelName, function (newValue, oldValue) {
}
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: '@',
modelName:'=',
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($scope.modelName, 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="modelName"'
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 {
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" model-name="result1" attr-
click-activation="true"
on-type="doSomething" on-select="doSomethingElse"></autocomplete>
<autocomplete url="url2" model-name="result2" attr-
click-activation="true"
on-type="doSomething" on-select="doSomethingElse"></autocomplete>
</div>
[$编译:nonassign]误差
当指令定义了隔离作用域属性时,会发生此错误(在指令定义的scope选项中使用= mode)但是该指令与一个不可赋值的表达式一起使用。
为了使双向数据绑定工作,必须能够将新值写回用表达式定义的路径。
您错过了添加属性autocompleteRequired
,因为您在隔离作用域中要求它,因此您需要添加具有autocomplete-required="true"
等值的autocomplete-required
属性
标记
<s:bind path="${path}">
<autocomplete url="${url}" name="${path}" model-name="${path}"
click-activation="true"
autocomplete-required="true"
on-type="doSomething" on-select="doSomethingElse">
</autocomplete>
</s:bind>
相关文章:
- 铬:“;未捕获的语法错误:意外的标记:"
- 可以设置“;文件名"发生错误时显示的内联脚本标记的
- JS表单提交"无法使用Chrome数据保护程序加载此页面.尝试重新加载页面.调试信息:POST CISmtuK
- 检测电话窃听,即:<a href="电话:xxx">在UIWebview上
- 使用“+="操作人员
- //而不是在src=“”上使用http://"属性
- "未捕获的语法错误:意外的标记}"
- 可以<脚本类型=“;text/javascript”>window.location=“/"</
- "实例范围”;TypeScript类的getter/setter
- Javascript复选框函数:;缺少:在属性id之后"
- "“;变量未引用正确的对象
- "日期“;AJAX请求返回的类型值未定义
- 得到"TypeError:无法读取属性'filename'未定义的“;调用“npm start
- Soundcloud api"未捕获的类型错误:无法读取属性'uri'“未定义”;
- "工具提示"jQuery插件坏了
- "锻造;React中的表达式
- 图像可以从源<img src=""/>.TEXT可以在没有javascript的情况下从外部
- 错误:[$compile:nonassign]表达式'未定义'与指令'内容可编辑'是不可
- 如何提取“;href"最近列表项中的属性值
- CKEditor如何允许href="javascript:void(0)"在小部件中