2014-01-28 2 views
4

У меня есть контроллер MyCtrl и директива myText. Когда изменяется модель в MyCtrl, я хочу обновить директиву textareamyText, вставив текст в текущую позицию/каретку.Директива Angularjs для вставки текста в textarea caret

Я попытался повторно использовать код из этого Inserting a text where cursor is using Javascript/jquery

Мой код: http://plnkr.co/edit/WfucIVbls2eekL8kUp7e

Вот мой HTML:

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link href="style.css" rel="stylesheet" /> 
    <script data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.js" data-require="[email protected]"></script> 
    <script src="app.js"></script> 
    </head> 

    <body> 
    <div ng-controller="MyCtrl"> 
     <input ng-model="someInput"> 
     <button ng-click="add()">Add</button> 
     <p ng-repeat="item in items">Created {{ item }}</p> 
    </div> 

    <textarea my-text=""> 

    </textarea> 

    </body> 

</html> 

Javascript:

var app = angular.module('plunker', []); 

app.controller('MyCtrl', function($scope, $rootScope) { 
    $scope.items = []; 

    $scope.add = function() { 
    $scope.items.push($scope.someInput); 
    $rootScope.$broadcast('add', $scope.someInput); 
    } 
}); 

app.directive('myText', ['$rootScope', function($rootScope) { 
    return { 
    link: function(scope, element, attrs) { 
     $rootScope.$on('add', function(e, val) { 
     console.log('on add'); 
     console.log(val); 

     if (document.selection) { 
      element.focus(); 
      var sel = document.selection.createRange(); 
      sel.text = val; 
      element.focus(); 
     } else if (element.selectionStart || element.selectionStart === 0) { 
      var startPos = element.selectionStart; 
      var endPos = element.selectionEnd; 
      var scrollTop = element.scrollTop; 
      element.value = element.value.substring(0, startPos) + val + element.value.substring(endPos, element.value.length); 
      element.focus(); 
      element.selectionStart = startPos + val.length; 
      element.selectionEnd = startPos + val.length; 
      element.scrollTop = scrollTop; 
     } else { 
      element.value += val; 
      element.focus(); 
     } 

     }); 
    } 
    } 
}]) 

Это не работает сейчас, потому что element не является объектом DOM. Здесь ошибка:

TypeError: Object [object Object] has no method 'focus' 

ВОПРОС: Так что мой вопрос, как это исправить? Или как получить объект real DOM от объекта углового элемента?

ответ

10

Try:

var domElement = element[0]; 

DEMO

+0

Nice. Как я пропустил это .LOL –

+0

Этот код, похоже, не обновляет область действия, и когда я пытаюсь вызвать $ apply, я получаю «$ digest уже в процессе» ... Как мне изменить переменную области видимости, связанную с этим текстовая область? – buzali

+0

@buzali: эта директива была разработана как «readonly». Нет смысла использовать это для обновления области. Например, нет информации о том, какую модель обновить, она просто слушает событие «добавить», которое может происходить из любого места и просто обновляет текст. –

5

Short anwser:

element[0] 

даст вам реальную DOM Element.

Длинный ответ:

angular.element всегда обеспечивает jqLite селектор, который похож на результирующий набор задается выбором JQuery. Это набор элементов HTML.

link функция метода вызывается со следующими Params: scope, element, attrs и ctrl.

element предоставляется как набор одного элемента DOM, к которому прилагается директива. Таким образом, первым элементом является фактический элемент HTML.

I changed your code so that it should(?) work

+0

Лучший ответ, чем принятый. Но демо-код не вставляет текст в текущую позицию/каретку, как было задано. – MCollard

Смежные вопросы