这个错误是什么"[$compile:nonassign]"在angularjs指令中

What is this error "[$compile:nonassign]" in angularjs directive

本文关键字:quot nonassign 指令 angularjs 错误 是什么 compile      更新时间:2023-09-26

我正在写一个指令,并在控制台中得到以下内容:

错误:[$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>