AngularJS : Initializing isolated scope inside a directive

眉间皱痕 提交于 2019-12-22 07:18:12

问题


I have created a directive that accepts some attributes and initializes the isolated scope with these attributes. If an attribute isn't specified, then the isolated scope should be initialized with a calculated value.

I added a link function that inspects the scope and initializes the default values (if no value has been set using the attributes). The scope has been initialized, but if I set a default value then it will be overwritten later by the framework.

A workaround is to use $timeout(...) and set it afterwards, but this seems too much of 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 have prepared a JSFiddle to illustrate what is happening.

  • msg1 is initialized via the attribute and has the correct value at all times.
  • msg2 is not initialized via an attribute, but can be set using an attribute. This value is overwritten after the link method has been called.
  • msg3 is not initialized via an attribute, and this isn't even possible. This value is set when constructing the controller and works fine.

It seems that AngularJS creates the scope and updates its value after the controller is created and the directive is linked into the DOM. Can anyone tell me the recommended way to do this?


回答1:


You have to operate on the attributes themselves if you want to set defaults for '@' type binding. Read about $compile

You can do it in the compile 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 use the link function as well.

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 that there is a binding with the attribute setup which overrides your changes to that scope variable. We need to modify the attribute that the value is being taken from.

@ or @attr - bind a local scope property to the value of DOM attribute. The result is always a string since DOM attributes are strings




回答2:


You can try initializing your $scope attributes in the controller of the directive, rather than the linking function. When the controller is initialized, the scope should already be set.




回答3:


I know this is an old one but I came across it looking for an answer and while I didn't get it, I did update your fiddle to get this example working.

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();

};


来源:https://stackoverflow.com/questions/22967024/angularjs-initializing-isolated-scope-inside-a-directive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!