AngularJS:在指令中初始化隔离作用域

5
我创建了一个指令,接受一些属性并使用这些属性初始化隔离作用域。如果未指定属性,则应使用计算出的值初始化隔离作用域。
我添加了一个链接函数来检查作用域并初始化默认值(如果没有使用属性设置值)。作用域已初始化,但如果我设置默认值,则稍后将被框架覆盖。
一种解决方法是使用$timeout(...),然后在之后进行设置,但这似乎太过于繁琐。
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);
    }
  };
});

我已经准备好了一个JSFiddle,以说明发生了什么。
  • msg1 通过属性初始化,始终具有正确的值。
  • msg2 不是通过属性初始化的,但可以使用属性设置。此值在链接方法被调用后被覆盖。
  • msg3 并没有通过属性初始化,这甚至不可能。该值在构造控制器时设置,正常工作。

看来AngularJS在创建作用域并将其值更新到控制器创建和指令链接到DOM之后。有人能告诉我推荐的做法吗?

3个回答

2

如果您想为@类型的绑定设置默认值,您必须直接操作属性。在$compile中了解更多信息。

您可以在编译函数中进行操作:

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

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

或者您也可以使用链接函数。


(注:该内容为HTML代码,已翻译)
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/

这是因为属性绑定覆盖了你对该作用域变量所做的更改。我们需要修改取值的属性。

@ 或 @attr - 将本地作用域属性绑定到 DOM 属性的值上。结果始终是字符串,因为 DOM 属性是字符串。


0

我知道这是一个老问题,但我在寻找答案时遇到了它,虽然我没有得到答案,但我更新了你的fiddle以使此示例工作。

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
你可以尝试在指令的控制器中初始化 $scope 属性,而不是链接函数。当控制器被初始化时,作用域应该已经设置好了。

这是我最初尝试的方法,因为我认为控制器应该控制作用域(而不是链接函数)。控制器的初始化甚至在它被链接之前就完成了。结果是相同的。 - Ramon de Klein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接