2016-04-19 3 views
0

aktualisieren Ich habe diesen Code, der Eingabe von einem Eingabebereich und fügt den Text an der Caret-Position in einem Textbereich, der Einfügeteil funktioniert genau aber Das ng-Modell des Textbereichs kann nicht aktualisiert werden. Hier ist der Codewie man ng-modell von textarea nach manueller einfügung von einigen text in es

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) { 
 
     var domElement = element[0]; 
 

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

 
     }); 
 
    } 
 
    } 
 
}])
<!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 src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></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> 
 
    <p>add some text and change caret position and insert test using input area above</p> 
 
    <textarea my-text="" ng-model="textarea"> 
 
    </textarea> 
 
    <p>{{textarea}}</p> 
 
    </body> 
 

 
</html>

Antwort

0

Der schnellste Lösung, um Ihren Code, den ich mir vorstellen kann hinzugefügt wird unten. Im Grunde fordern Sie den ng-Modell-Controller in Ihre Anweisung ein und informieren Sie ihn, wenn sich der Wert geändert hat.

Ein wenig off-topic, aber Ihre myText-Direktive über den globalen Bereich (in Form von $ rootScope. $ On) gesteuert werden riecht schlecht für mich.

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 { 
 
    require: '^ngModel', // request our containing ng-model controller 
 
    link: function(scope, element, attrs, ngModelCtrl) { // DI 
 
     $rootScope.$on('add', function(e, val) { 
 
     var domElement = element[0]; 
 

 
     if (document.selection) { 
 
      domElement.focus(); 
 
      var sel = document.selection.createRange(); 
 
      sel.text = val; 
 
      domElement.focus(); 
 
     } else if (domElement.selectionStart || domElement.selectionStart === 0) { 
 
      var startPos = domElement.selectionStart; 
 
      var endPos = domElement.selectionEnd; 
 
      var scrollTop = domElement.scrollTop; 
 
      domElement.value = domElement.value.substring(0, startPos) + val + domElement.value.substring(endPos, domElement.value.length); 
 
      domElement.focus(); 
 
      domElement.selectionStart = startPos + val.length; 
 
      domElement.selectionEnd = startPos + val.length; 
 
      domElement.scrollTop = scrollTop; 
 
     } else { 
 
      domElement.value += val; 
 
      domElement.focus(); 
 
     } 
 
     // inform ng-model that the value has changed 
 
     ngModelCtrl.$setViewValue(domElement.value); 
 
     }); 
 
    } 
 
    } 
 
}])
<!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 src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></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> 
 
    <p>add some text and change caret position and insert test using input area above</p> 
 
    <textarea my-text="" ng-model="textarea"> 
 
    </textarea> 
 
    <p>{{textarea}}</p> 
 
    </body> 
 

 
</html>

+0

Nein, ich benutze kein rootscope, es ist nur ein schnelles Beispiel, das ich aufgestellt habe, anstatt den riesigen Code zu posten. –

+0

und jawohl, es repariert es –

+0

jedoch könnten Sie tatsächlich erwägen, die Gültigkeitsbereich-Variable in Javascript zu setzen, da dies automatisch die Änderungen verdaut. Sieh meine Antwort – nicost

-2

Versuchen Sie, diese Änderung in der HTML-Datei zu machen -

<textarea my-text="" ng-bind="someInput"> 
</textarea> 
+0

;-) aktualisieren Diese nicht den Text-Bereich Modell, und ich denke, beantwortet die ursprüngliche Frage nicht. – Mike

0

Es ist auch eigentlich nicht viel in Ihrem Code zu ändern. Sie benutzen einfach nicht den $ scope, resp. $ rootScope-Variable korrekt. Wenn Sie die $ rootScope Variable $ rootScope.textarea statt domElement.value aktualisieren, Winkel tut all die "magische" Bindung für Sie

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) { 
 
     var domElement = element[0]; 
 

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

 
     }); 
 
    } 
 
    } 
 
}])
<!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 src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></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> 
 
    <p>add some text and change caret position and insert test using input area above</p> 
 
    <textarea my-text="" ng-model="textarea"> 
 
    </textarea> 
 
    <p>{{textarea}}</p> 
 
    </body> 
 

 
</html>