3

I have a text area that is already bound with a filter, so it'll load with the correct info on page load, but now I want to change a model when the text area is changed, but once I add a model and change event the initial binding stops working.

Here is the HTML as a one way binding, which works:

<textarea>{{mainboard | textboard}}</textarea>

My thinking was that I would add a change event, which errors without a model, so I added a model, like so:

<textarea ng-model="textmainboard" ng-change="updateMainboard()">{{mainboard | textboard}}</textarea>

How can I have a two way binding, with the one way being filtered (the filter in this example is the textboard service)?

EDIT: Here is a js fiddle of me trying to do the blur, which shouldn't require a model: http://jsfiddle.net/vjkgH/

EDIT: The exact use case is I have a list of items. The list of items is displayed as li elements and displayed in a textarea with duplicates shown as "3x itemb". The list of items can be changed in two way, by hitting an add button or by changing the textarea.

Here is an example state:

<ul>
 <li>item1</li>
 <li>item1</li>
 <li>item2</li>
</ul>
<textarea>
 2x item1
 1x item2
</textarea>
Sophie McCarrell
  • 2,831
  • 8
  • 31
  • 64
  • Always make sure your `ng-model` has a dot in it. For example, `mainboard.text` (you have to create a `mainboard` object in the scope). It's most likely that you're assigning to a child scope and losing reference to the parent scope. – sirhc Aug 27 '13 at 04:28
  • I tried adding mainboard.text as the ngmodel and adding $scope.textmainboard = {}; in my controller, but it still doesn't respond while also having the {{}} binding. Btw I have a temporary fix, which is to use ngblur..., which essentially does the same thing that I want. In fact I think this is just a case of me being confused about the use case of ngchange... it isn't meant to simply replace the change event, it is meant to become a two way binding, unlike blur or click, etc. – Sophie McCarrell Aug 27 '13 at 04:36
  • hmmm... it seems ngblur isn't triggering either :( no errors or anything... the function simply isn't called. – Sophie McCarrell Aug 27 '13 at 04:42
  • There are many typos in your comment. I'm not sure if you also made those typos in the code. Could you please post more code (at least about the scope) and update the answer, or use JSFiddle? – sirhc Aug 27 '13 at 04:45
  • It should work, i create a sample fiddle here http://jsfiddle.net/cmyworld/gsw9Q/ and it seems to work. – Chandermani Aug 27 '13 at 04:51
  • hmmm, thanks chander. nm you already have a filter... why the heck doesn't mine work. I'm going to look deeper for issues for a few minutes and if I can't figure it out I'll post here again. – Sophie McCarrell Aug 27 '13 at 04:56
  • Chander, your filter doesn't work. Try having it actually do something and you'll find it doesn't actually work. (I had it append the string " world" to it.) – Sophie McCarrell Aug 27 '13 at 05:03
  • hmmm, so it would seem, I can't get the blur event to work at all. No matter what. Can someone show me a fiddle where blur is working on a textarea? (focus doesn't work either, but click works just fine... hmmm) – Sophie McCarrell Aug 27 '13 at 05:18
  • hmmm... I found the SO QA I had opened a weeks ago, that I lost. I'm going to try it to solve my over-arching problem: http://stackoverflow.com/questions/11616636/how-to-do-two-way-filtering-in-angular-js?rq=1 – Sophie McCarrell Aug 27 '13 at 05:59
  • Using the method in the other SO QA still doesn't work, unfortunately my case is just a little different, because I'm dealing with an array, I think. I dunno... I'm trying to figure it out. I'm probably missing something silly. – Sophie McCarrell Aug 28 '13 at 21:33
  • Whelp after a trying just about everything and eventually getting some advice from IRC, I found the issue, but not a great solution. I'll post the answer. – Sophie McCarrell Aug 29 '13 at 04:23

1 Answers1

1

For my own use case, the issue was that angular only runs $watch [in other words, updates your DOM] when your new variable, doesn't equal your old variable, unless the third parameter of the $watch function is set to true.

for an ng-model on a text area or any text thing, the third parameter is always false, so it compares the old array to the new array, which are equal to the same reference, and therefor, angular doesn't think the array changed.

I've requested a feature on github from the angular community that an option is somehow added to allow objectEquality to be set to true when doing ng-model. Otherwise you would need to write your own directive that mimics ng-model, but also sets the $watch's third parameter to true.

So, to get my desired result, I used the answer to this SO QA: How to do two-way filtering in angular.js? and have all my updates to the array, clone the array, so there is always a new reference. The inefficiency worries me, but my old laptop appears to handle it lightning fast, so good enough.

Community
  • 1
  • 1
Sophie McCarrell
  • 2,831
  • 8
  • 31
  • 64