Problem with ion-content and scope vars inside function

Hi,

scope variables are undefined inside controller function if input field with ng-model is inside ion-content.

If I place the same input field outside ion-content, everything works as expected.

I think I maybe missing something because if I recall properly several versions back that worked as it should.

Please help.

Thanks

I’m guessing it’s because you aren’t using “dot notations”.

$scope.volume = 5

You need to use :

$scope.data = { 'volume' : 5}

Definitive Resource : https://github.com/angular/angular.js/wiki/Understanding-Scopes

Thank you for your answer. But I’m still a bit confused, and probably wasn’t clear enough. Here is the simple code that worked for me quite nice until put into ion-content directive.
In the controller:

$scope.clickMe = function(){
     console.log( $scope.someVar );
};

And in the ion-content:

<input type="text" ng-model="someVar" />
<button class="button" ng-click="clickMe()">Click</button>
{{someVar}}

Now what’s interesting is that writing in a field immediately binds on screen, but clicking on a button yields
undefined in a console.
Further, what’s confusing me is that this behavior manifests only if input field is inside ion-content directive, but if you put everything out, even in a sub-header for example, it works quite as I expected.

I’m relatively new to whole angular + ui-router + ionic stack so please bare with me, but this is really confusing.
I still have a feeling that I’m missing something, but I’m not sure because it behaves differently in different view directives.

Thank you for your patience,

Igor

The problem is specific with ion-content because of the way this directive is defined in the Ionic source code. It specifically creates it’s own child scope.

.directive('ionContent', [
  '$parse',
  '$timeout',
  '$ionicScrollDelegate',
  '$controller',
  '$ionicBind',
function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    require: '^?ionNavView',
    scope: true,
    template:
    '<div class="scroll-content">' +
      '<div class="scroll"></div>' +
    '</div>',

Because of this and the way inheritance works in JavaScript, you cannot use 2 way binding. Basically your $scope.clickMe is defined in you controller and is just created as a new primitive to the scope of ion-content. It is not copied by reference like an object would be.

Reread that article I linked to. It’s critical in understanding how this all works and overcoming these issues.

I wonder if there is a quick fix: Plunker - Untitled

    $scope.add = function(item) {
      alert("adding " + item + " but due to isolated scopes cannot clear search field");
      
      $scope.searchText = "";
    }

I have a list and search field sitting in ion-content and I would like to clear the filter after adding the item.

Possible?
(Thanks)

“dot notation” saves the day : http://plnkr.co/edit/2ZNeHRmYQ1cE3zWLpo2X?p=preview

Of course: http://www.youtube.com/watch?v=ZhfUv0spHCY&feature=share&t=30m51s

(Misko Hevery AngularJS Best Practices)

This is an old topic but still relevant.

I was able to get around the problem by binding my inputs to $parent.someModel.

So in the example above, changing the view to

<input type="text" ng-model="$parent.someVar" />
<button class="button" ng-click="clickMe()">Click</button>
{{someVar}}

Will allow you to properly bind the input box to the $scope from your controller as expected.

This worked perfectly and was all that was needed. Thanks!

hia thanks for your solution it saves my time so much

This fixed an issue on which i spent close to 3 hrs. Thanks a lot.