0

ng-model does not affect the scope and I can't understand why.

Here is most of my HTML:

<ion-view view-title="{{ inputType | uppercase | translate }}">

  <ion-content class="padding">

    <div class="list">
      <label class="item item-input">
        <input ng-model="amount" class="text-align-center" type="number" placeholder="{{ 'AMOUNT' | translate }}">
      </label>
    </div>

    <button class="button button-block button-stable" ng-click="okAmount()">{{ 'SAVE' | translate }}</button>

  </ion-content>
</ion-view>

Here is most of my controller:

(function(){
  angular.module('mb')
    .controller('EnterAmountCtrl', ['$scope', '$state', '$filter', '$translate',
      function($scope, $state, $filter, $translate) {

        $scope.amount = '';

        $scope.okAmount = function() {
          console.log($scope.amount);
        };

      }]);
})();

I don't think that this can be a scoping issue. There are no nested controllers. Routing is handled like this:

    $stateProvider.state('enter-amount', {
      url: '/enter-amount/:inputType',
      templateUrl: 'templates/enter-amount.html',
      controller: 'EnterAmountCtrl'
    });

Regardless of what I write in the text box, $scope.amount remains undefined. What might be causing this?

4
  • 1
    Can you include the rest of your html? This looks like a scoping issue, but it's hard to say without seeing the rest of it. Commented Nov 20, 2015 at 16:00
  • @nmarsh: Thank you for looking for a solution. I've edited and added to my post. I hope it clarifies the problem more. Commented Nov 20, 2015 at 16:05
  • 1
    To confirm if it's a scope issue, just put a dot in your model. In fact, always put a dot in your model. So instead of ng-model="account" (where account is a primitive value), do ng-model="myData.account" (where myData is an object that will survive the prototypical inheritance and not create scope issues). BTW, nested controllers are not the only way to create these issues, ng-if, ng-include, ng-repeat, etc. also create new scopes. Commented Nov 20, 2015 at 16:09
  • When dealing with plain value(number, string, boolean) scope variables you have to be careful not to be modifying a child scope variable while your intent is to modify a parent scope. The best approach is to define a container object on a parent and then access container.value as your model on the children scopes. that way the container gets inherited through the children, and will not be room for confusion. This is the principle behind the controllerAs syntax you could benefit from Commented Nov 20, 2015 at 16:09

1 Answer 1

4

Updated answer:

Following up on Sunil D and Dayan Moreno's comments to the question, throwing the primitive value inside an object is the best approach, and avoids having to use $parent in your code:

ng-model='object.amount'

As long as object doesn't exist in the child scope, it will refer to the object variable found in the parent scope and set the amount value appropriately.

Original answer:

Having not used ion yet, I would assume that either ionView or ionContent is a directive which creates its own scope.

You're setting the value property of a child scope, then trying to access the value property of the parent scope. Accessing the parent scope's amount value might solve the issue for you:

ng-model='$parent.amount'
Sign up to request clarification or add additional context in comments.

3 Comments

That worked! Messed up :-) In the end I went with the solution proposed by Sunil D and Dayan Moreno Leon, to whar the primitive in an object.
Sunil D and Dayan Moreno definitely had the right idea: I think throwing the primitive into an object is a much cleaner route than throwing $parent around.
Still, your answer was a good confirmation to it being a scope issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.