Andrew Samuelsen
Andrew Samuelsen

Reputation: 5432

Select created by directive will receive updates but not update others in Angular

I have a directive as follows. The <select> created by the directive will update when I change the scope var bound to it in ng-model, but when I change the <select> itself it doesn't update the scope var. I think I'm missing registering a $watch in the link, but I'm not sure... Thanks for the help.

template.html

<div ng-repeat="searchField in searchFields">
    <select-search-field label="{{searchField.label}}" field="$parent[searchField.field]"></select-search-field>
</div>

resulting html

<div>
    <label>Landing Gear</label><br>
        <select ng-model="gear">
        <option value="">Any</option>
        <option value="fixed">Fixed</option>
        <option value="retractable">Retractable</option>
    </select>
</div>

controller.js

$scope.searchFields = [{
    label: 'Landing Gear'
    field: 'gear'
}];

$scope.gear = ''; //This is getting sent to directive in "field" (the $parent[] part)

directive.js

.directive('selectSearchField',function() {
  function template() {
    return '<label>{{label}}</label><br>' + 
      '<select ng-model="field">' + 
      '<option value="">Any</option>' + 
      '<option value="fixed">Fixed</option>' + 
      '<option value="retractable">Retractable</option>' + 
      '</select>';
  }

  return {
    restrict: 'E',
    scope: {
      label: '@',
      field: '=',
      options: '='
    },
    template: template()
  };
});

Edit: Here are the files on github: https://github.com/andypandy/littleplanefinder (see stuff in public/js/controllers.js and public/js/directives.js

Also: see it live: http://www.littleplanefinder.com

Upvotes: 0

Views: 61

Answers (1)

hassassin
hassassin

Reputation: 5054

It looks like you are showing the label using {{label}} but updating field, so you won't see updates there since label is never updated.

Also you don't need any of the $parent stuff for the field attribute, it will evaluate it as part of the isolated scope.

I made a fiddle that does what you are looking for http://jsfiddle.net/G5UCm/3/

You can click the get label button to alert the value that the controller sees, so you can be sure that the two way data-binding is set up correctly.

Here are the relevant parts:

// in markup in the scope of the controller
<select-search-field field="searchField.field">
</select-search-field>
// part of the template, make sure to display the item we are changing!
return '<label>{{field}}</label><br>' + 

Edit: Updating for the new info

Oh so you are trying to use ng-model on the parent gear property. This is a little weird because you are trying to get around the isolation. If you just don't isolate you can just inherit scope variables. Alternatively, you still pass the field as a two-way data binding and just use the model on the parent, like this:

'<select ng-model="$parent[field]">' + 

Here is the updated fiddle: http://jsfiddle.net/G5UCm/4/

Hope this helped!

Upvotes: 1

Related Questions