AngularJS:在指令中初始化隔离范围

时间:2014-04-09 15:20:16

标签: angularjs angularjs-directive angularjs-scope

我创建了一个接受一些属性的指令,并使用这些属性初始化隔离的作用域。如果未指定属性,则应使用计算值初始化隔离范围。

我添加了一个链接函数,用于检查范围并初始化默认值(如果没有使用属性设置值)。范围已初始化,但如果我设置了默认值,那么框架将在稍后覆盖它。

解决方法是使用$ 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 个答案:

答案 0 :(得分:2)

如果要为&#39; @&#39; 类型绑定设置默认值,则必须对属性本身进行操作。阅读$compile

您可以在编译功能中执行此操作:

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

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

或者您也可以使用链接功能。

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属性,结果总是一个字符串   字符串

答案 1 :(得分:0)

您可以尝试在指令的controller中初始化$ scope属性,而不是链接函数。初始化控制器时,应该已经设置范围。

答案 2 :(得分: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();

};