AngularJS: Initializing an isolated area inside a directive

I created a directive that accepts some attributes and initializes an isolated area with these attributes. If the attribute is not specified, then the isolated area must be initialized with the calculated value.

I added a communication function that checks the scope and initializes the default values ​​(if the value has not been set using the attributes). The volume was initialized, but if I set the default value, it will be overwritten later by the framework.

A workaround is to use $ timeout (...) and install it later, but it seems too big due to a hack.

function ($timeout) { return { scope: { msg1: '@', msg2: '@' }, template: '<div>{{msg1}} {{msg2}} {{msg3}}</div>', link: function ($scope, $elt, $attr) { var action = function() { if (!$scope.msg2) $scope.msg1 = 'msg1'; if (!$scope.msg2) $scope.msg2 = 'msg2'; if (!$scope.msg3) $scope.msg3 = 'msg3'; }; action(); //$timeout(action, 0); } }; }); 

I prepared a JSFiddle to illustrate what happens.

  • msg1 is initialized through an attribute and always has the correct value.
  • msg2 is not initialized with an attribute, but can be specified using an attribute. This value is overwritten after the link method is called.
  • msg3 is not initialized via an attribute, and this is not even possible. This value is set when the controller is built and works fine.

It seems that AngularJS creates the scope and updates its value after the controller is created, and the directive is associated with the DOM. Can someone tell me the recommended way to do this?

+4
source share
3 answers

You need to operate on the attributes themselves if you want to set default values ​​for bindings of type '@ . Read about $ compile

You can do this in the compilation function:

 compile: function(element, attrs) { if (!attrs.msg1) attrs.msg1 = 'msg1'; if (!attrs.msg2) attrs.msg2 = 'msg2'; } 

http://jsfiddle.net/5kUQs/9/

OR you can also use the link function.

 link: function ($scope, $elt, attrs) { var action = function() { console.log('msg1:' + $scope.msg1 + ', msg2:' + $scope.msg2 + ', msg3: ' + $scope.msg3); if (!attrs.msg1) attrs.msg1 = 'msg1'; if (!attrs.msg2) attrs.msg2 = 'msg2'; if (!attrs.msg3) attrs.msg3 = 'msg3'; }; action(); } 

http://jsfiddle.net/5kUQs/13/

The reason for this is because there is a binding to setting an attribute that overrides your changes to this scope variable. We need to change the attribute from which the value is taken.

@ or @attr - bind a local area property to the value of the DOM attribute. The result is always a string because the DOM attributes of a string

+2
source

You can try to initialize the $ scope attributes in the controller directive of the directive, rather than the binding function. When the controller is initialized, the scope should already be set.

0
source

I know this is old, but I came across it looking for an answer, but until I understood it, I updated fiddle to make this example work.

 function MyController($scope){ var c = this; c.msg1 = $scope.msg1; c.msg2 = $scope.msg2; var action = function() { console.log('msg1:' + $scope.msg1 + ', msg2:' + $scope.msg2 + ', msg3: ' + $scope.msg3); if (!c.msg2) c.msg1 = 'msg1'; if (!c.msg2) c.msg2 = 'msg2'; if (!c.msg3) c.msg3 = 'msg3'; }; action(); }; 
0
source

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


All Articles