AngularJS : Two-way binding between a textarea and ng-repeat-ed inputs

I was going to ask this as a question, but I figured out a solution. So at this point, I'm looking for a critique of my solution.

  1. I've got a static textarea, and an input with an ng-repeat directive.

  2. As the user types a sentence into the textarea, a input is rendered for each word in the sentence.

  3. Then if the user updates the text in any input, the corresponding word in the textarea sentence is updated (really the whole sentence is recreated).

Demo: http://plnkr.co/edit/bSjtOK?p=preview

Questions

Keeping in mind that I'm only 2 weeks into my AngularJS learning:

  • Did I write this in the "angular" way?
  • Is there something I could have done better?
  • Am I violating any no-nos?

Abbreviated Code

HTML

<textarea ng-model="sentence" ng-change="parseSentence()" style="width: 100%; height: 15em;"></textarea>

<input type="text" ng-repeat="w in words" ng-model="w.word" ng-change="buildSentance(w)" />

JavaScript

function WordCtrl($scope, debounce) {

    $scope.words = [];
    $scope.sentence = 'Hello there how are you today?';

    // this is called when the textarea is changed
    // it splits up the textarea's text and updates $scope.words 
    $scope.parseSentence = function() {

        var words = $scope.sentence.split(/\s+/g);
        var wordObjects = [];

        for (var i=0;i<words.length;i++) {          
          wordObjects.push({word: words[i]});
        }

        if ((words.length == 1) && (words[0] === '')) {
          $scope.words = [];
        } else {
          $scope.words = wordObjects;
        }

    };

    $scope.parseSentenceDebounced = debounce($scope.parseSentence, 1000, false);

    $scope.buildSentance = function(w) {

        var words = [];

        for (var i=0;i<$scope.words.length;i++) {
          var word = $scope.words[i].word;
          if (word.replace(/\s+/g,'') !== '') {
            words.push(word);
          }
        }

        $scope.sentence = words.join(' ');

        // if the user puts a space in the input
        // call parseSentence() to update $scope.words
        if (w.word.indexOf(' ') > -1) {
          $scope.parseSentenceDebounced();
        }

    }

    $scope.parseSentence();

}

Interesting issue you are having. I put your code on my page and the first thing I noticed is that you cannot pass debounce in the controller method.

Next Problem I noticed is that you have an ng-change that changes the values on another box with ng-change. I changed the event to Keypress to stop the digest in a digest.

Here it is working in JSFiddle enter link description here

The code:

HTML

    <body ng-app="portal">
    <div ng-controller="WordCtrl">
    <textarea ng-model="sentence" ng-keypress="parseSentence()" style="width: 100%; height: 15em;"></textarea>
    <input type="text" ng-repeat="w in words" ng-model="w.word" ng-keypress="buildSentance(w)" />
    </div>
    </body>

Javascript

angular.module("portal",[]).controller("WordCtrl",function($scope) { 
    $scope.words = [];
    $scope.sentence = 'Hello there how are you today?';
    $scope.parseSentence = function () {
        var words = $scope.sentence.split(/\s+/g);
        var wordObjects = [];
        for (var i = 0; i < words.length; i++) {
            wordObjects.push({ word: words[i] });
        }
        if ((words.length == 1) && (words[0] === ''))
        {
            $scope.words = [];
        }
        else
        {
            $scope.words = angular.copy(wordObjects);
        }
    }

    $scope.buildSentance = function (w) {

        var words = [];

        for (var i = 0; i < $scope.words.length; i++) {
            var word = $scope.words[i].word;
            if (word.replace(/\s+/g, '') !== '') {
                words.push(word);
            }
        }

        $scope.sentence = words.join(' ');

        // if the user puts a space in the input
        // call parseSentence() to update $scope.words
        if (w.word.indexOf(' ') > -1) {
            $scope.parseSentenceDebounced();
        }
    }
    $scope.parseSentence();

    });

Hope this solves your issue.