1

How do I assign default ngOptions through parent/child models?

In this question OP shows a way form parent/child relationships using ngOptions

template

<select ng-model="x.site" ng-options="s.site for s in data"></select>
<select ng-model="x.name" ng-options="b.name for b in x.site.buildings"></select>

controller

$scope.x = {};
$scope.data = [
    {
        "site" : "Brands Hatch",
        "buildings" : [
            { "name" : "Building #1" },
            { "name" : "Building #2" },
            { "name" : "Building #3" }
        ]
    },{
        "site" : "Silverstone",
        "buildings" : [
            { "name" : "Building #4" },
            { "name" : "Building #5" },
            { "name" : "Building #6" }
        ]
    }
];

What you will see in this fork is that the dropdowns do not have any default values --- That is, the default option is "blank". In a normal use case this is a non issue, and default options are easily configurable through the controller which is explained well in the docs.

  • How do I eliminate "blank" options for parent/child models using ngOptions?
  • How do I select default options either through the view or dynamically through the controller. It's important to remember here that the child default select options are first dependant on the parents selected option.
Community
  • 1
  • 1
Dan Kanze
  • 18,485
  • 28
  • 81
  • 134

1 Answers1

2

The blank item is caused by the empty model value. You can try to put the following code at the end of the controller. The trick is to initialize site, building and floor when the page is loaded as well as when the site value is changed. Hope it helps.

$scope.selected = {
    site: $scope.data[0],
    building: $scope.data[0].buildings[0],
    floor: $scope.data[0].floors[0]
};

$scope.$watch('selected.site', function () {
    console.log($scope.selected.site);
    $scope.selected = {
        site: $scope.selected.site,
        building: $scope.selected.site.buildings[0],
        floor: $scope.selected.site.floors[0]
    };
});
zs2020
  • 53,766
  • 29
  • 154
  • 219
  • Is there an alternative way to solve this problem without declaring local models at all?... Even if it means changing the way the parent/child relationship is formed or the directives are used differently. It seems really dirty to explicitly declare an index. – Dan Kanze Aug 02 '13 at 18:44
  • I will think about it. It seems Angularjs binds the data anyway using ng-model for each ddl, maybe you can try to reinvent the `select` directive. Your question is great btw :) – zs2020 Aug 02 '13 at 18:52
  • @DanKanze I just saw this [thread](http://stackoverflow.com/questions/12654631/why-does-angularjs-include-an-empty-option-in-select) and it seems the solution is just simply give the initial value of the model. – zs2020 Aug 02 '13 at 18:58
  • Thanks! I'm also particularly interested how to solve this problem with async data... I'm running into a senario where I have to wrap this solution in a callback --- because the local model cant get set on an index that hasnt yet been declared and becomes `undefined`. – Dan Kanze Aug 02 '13 at 19:37
  • @DanKanze I think you can create factory method and return `promise` so you can add the callback in the controller by chaining the `promise` – zs2020 Aug 06 '13 at 14:48