AngularJS指令:与指令一起使用的表达式'undefined'是不可赋值的

pos*_*est 20 angularjs angularjs-directive

我是一个2周大的Angular noob,我现在已经尝试了我的第一个指令超过一天了.:P我已经读过这个这个,看起来很好的指令介绍和一堆Stackoverflow答案,但我不能让这个工作.

<div ng-app="App" ng-controller="Main">
  <textarea caret caret-position="uiState.caretPosition"></textarea>
  {{uiState.caretPosition}}
</div>
Run Code Online (Sandbox Code Playgroud)

angular.module('App', [])
  .controller('Main', ['$scope', function ($scope) {
    $scope.uiState = {};
    $scope.uiState.caretPosition = 0;
  }])


  .directive('caret', function() {
    return {
      restrict: 'A',
      scope: {caretPosition: '='},
      link: function(scope, element, attrs) {
        var $el = angular.element(element);
        $el.on('keyup', function() {
          scope.caretPosition = $el.caret();
        });
      }
    };
  }); 
Run Code Online (Sandbox Code Playgroud)

小提琴就在这里.我基本上试图在文本框中获得插入位置.我在小提琴中使用这个jQuery插件(.caret()方法的源代码,它应该只返回一个数字).

我的问题是

  1. 我甚至需要一个指令吗? Ben Nadel说最好的指令就是你不必写的指令(对此而言!)
  2. 如果是,这是正确的指令方式吗?即具有双向约束变量的孤立范围?
  3. 如果是,当我在本地运行此代码时,我不断收到错误Expression 'undefined' used with directive 'caret' is non-assignable!.我已经阅读了文档,据我所知,我已经遵循了如何修复无效的说明.
  4. 奖励:为什么在jsfiddle中我没有得到这样的错误.小提琴只是默默地失败了.那是什么?

谢谢!

Lou*_*uis 21

我的解决方案在这里很难找到,但更容易实现.我不得不把它改成相当于;

  scope: {caretPosition: '=?'},
Run Code Online (Sandbox Code Playgroud)

(请注意,问号使该属性成为可选.在1.5之前,这显然不是必需的.)


Aus*_*eco 14

你很接近..主要问题是在角度不知道的事件中更改范围变量.当该事件发生时,您必须通过使用来告知角度有什么变化scope.$apply.

  $el.on('keyup', function() {
      scope.$apply( function() {
        scope.caretPosition = $el.caret();
      });
  });
Run Code Online (Sandbox Code Playgroud)

在这里工作小提琴

对于问题:

  1. 是的,我不认为有必要为此编写指令.
  2. 在这种情况下,它似乎很好.
  3. 不确定,jsfiddle没有问题.听起来你在carat="something"某处?检查以确保html与小提琴中的内容相同.
  4. 与3相同

另请注意,如果单击并移动插入符号,它将不会更新,因为它只是在侦听键盘.