I've got a custom defined directive in angularjs. Basically what I want to happen is the user will pick a value from a select box and that will append a value to an array. This causes my custom directive to be invoked and render a new element on the screen. I want the text field that the directive generates to bind to the controller's attribute.
Html
<device-list ng-repeat="device in devices" key="device.key" display-name="device.display_name" bind-prefix="descriptions"></device-list>
Directive
angular.module('device_list_tag', []).
directive('deviceList', function() {
return {
restrict: 'E',
require: '?ngModel',
scope: {
devices: '=',
key: '=',
displayName: '=',
bindPrefix: '@'
},
link: function(scope, element, attrs) {
var deviceListElement = $(element)
var containerDiv = $('<div>')
.addClass('row')
var labelTag = $('<label>').text(scope.displayName)
.addClass('span1')
var bindField = attrs.bindPrefix+'.'+scope.key
var textField = $('<input>')
.addClass('span3')
.attr('ng-model', bindField)
containerDiv.append(labelTag)
containerDiv.append(textField)
deviceListElement.append(containerDiv)
}
}
})
Controller
function DevicesCtrl($scope) {
descriptions = {}
}
It appears as though as ng-model is local to the directive's scope, how do I make it apply to the parent? If I have a bunch of text fields on the page like
<input ng-model="descriptions.test"/>
It works works except with the fields generated by the select box.
[(ngModel)]="overRideRate" is the short form of [ngModel]="overRideRate" (ngModelChange)="overRideRate = $event" [ngModel]="overRideRate" is to bind overRideRate to the input.value. (ngModelChange)="overRideRate = $event" is to update overRideRate with the value of input. value when the change event was emitted.
In short ngModel can't be used by itself within FormGroup When you use formControlName, ngModel does not activate or create a control (it's simply used as an @Input). formControlName just links to the existing input you created in your class.
The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.
Ok, I figured it out. It involved passing in my parent attribute as '=' (suggested by Tosh). I also had to make a call to $compile to make it recognize the ng-model directive. Here's the full code, I'm sure there's a way to do this cleaner but I'm just glad to have it working.
angular.module('device_list_tag', []).
directive('deviceList', function($compile) {
return {
restrict: 'E',
scope: {
devices: '=',
key: '=',
displayName: '=',
bindAttr: '=' // added
},
link: function(scope, element, attrs) {
console.log(scope)
var deviceListElement = $(element)
var containerDiv = $('<div>')
.addClass('row')
var labelTag = $('<label>').text(scope.displayName)
.addClass('span1')
var bindField = 'bindAttr.'+scope.key
var textField = $('<input>')
.addClass('span3')
.attr('ng-model', bindField)
$compile(textField)(scope) // added
containerDiv.append(labelTag)
containerDiv.append(textField)
deviceListElement.append(containerDiv)
}
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With