Using the ng model in the directive

I have a custom directive in angularjs. Basically, I want the user to select a value from the selection field and add the value to the array. This leads to the call of my custom directive and the display of a new element on the screen. I want a text field to be generated to bind to a controller 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 seems that since ng-model is local to the scope of the directive, how can I apply it to the parent? If I have a bunch of text fields on a page like

 <input ng-model="descriptions.test"/> 

It works only with the exception of the fields created in the selection window.

+6
source share
4 answers

Ok, I figured it out. It included passing my parent attribute as '=' (suggested by Tosh). I also had to make a $ compilation call so that it recognized the ng-model directive. Here is the complete code, I'm sure there is a way to make this cleaner, but I'm just glad it works.

 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) } } }) 
+9
source

Maybe you can add bindField: '=' to your scope definition. And use this variable to connect to the parent scope.

+2
source

You asking,

1) Update the parent array of areas, and we are editing the elements of the shape of the selection area. If so, I reproduced a similar script in this http://jsfiddle.net/W7YrZ/2/ script.

A summary of what I was trying to do.

1) Assign the umbilical attribute in ng-repeat current iteration element.

2) Then im evaluating this attribute inside the binding function in the context of the parent region, which gives a link (pointer) to one of the array objects in the parent region array here profiles .

3) Then, when @Mark Rajcok says, "primitives are copied by value, and objects are copied by reference." I bind this object to step 2 to the text fields in the template line.

+1
source

for reasons of jQuery code cleanliness in angular and to test javascript just replace the $ selector with angular.element

 $('<input>').addClass('span3') 

should be recorded

 angular.element('<input>').addClass('span3') 
-3
source

Source: https://habr.com/ru/post/926895/


All Articles