1

I recently spent over 4 hours before figuring out why my ng-model directive used in combination with ng-options was not correctly binding to the property within my controller. The <select> element was being properly initialized - receiving a value from the controller (parent) scope. But the child scope was not correctly updating the parent scope. After checking out the following questions and plunkers, I was able to develop a "work around" for this issue:

Helpful stackoverflow question 1

Helpful stackoverflow question 2

Basic Plunker

I found that the property I was binding to in my <select> element was binding to a property of the same name within a child scope of the controller - therefore not the value was not reflected as expected in the controller's scope. After changing

<select ng-options="asset as asset.Name for asset in allAssets" ng-model="selectedAsset" ng-change="lookupAssetPermissions()"></select>

to

    <select ng-options="asset as asset.Name for asset in allAssets" ng-model="$parent.selectedAsset" ng-change="lookupAssetPermissions()"></select>

The value in selectedAsset was correctly binding to the property in the controller's scope (as seen in the ng-change event handler). The entire context of my element is the following:

<!---outer div has controller level scope----->
<div>
    <!---inner div creates child scope with ng-if----->
    <div ng-if="true condition here">
        <!---select statement from above----->
        <select ng-model="$parent.selectedAsset">...</select>
    </div>
</div>

Do I have any other options in this scenario other than purposefully binding to the parent scope? If I had multiple child scopes (nested ng-if statements), would I need to alter the ng-model to bind to $parent.$parent.$parent....selectedAsset in order to update the value in my controllers scope? Are there any "best practices" on this topic?

1 Answer 1

1

Put all variables inside some object i.e.:

$scope.Model = {
  selectedAsset : 'mySelectedAsset1',
  selectedAsset2 : 'mySelectedAsset2',
  selectedAsset3 : 'mySelectedAsset3'
}

Then you can:

<div ng-repeat> //new scope
<div ng-repeat> // new scope
<input ng-model="Model.selectedAsset">

This also lows your 'dependency' on $scope, defining such Model object will show everyone who is reading your code what model u have.

Sign up to request clarification or add additional context in comments.

1 Comment

Clean. and Functional. I've seen this solution before but did not know the advantages of its use. Thanks a lot.

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.