【问题标题】:AngularJS : Initializing isolated scope inside a directiveAngularJS:在指令内初始化隔离范围
【发布时间】:2014-04-09 15:20:15
【问题描述】:

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

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

一种解决方法是使用 $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 之后创建范围并更新其值。谁能告诉我推荐的方法吗?

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    如果要为 '@' 类型绑定设置默认值,则必须对属性本身进行操作。阅读$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 属性是 字符串

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 这是我一开始尝试的,因为我认为控制器应该控制范围(而不是链接功能)。控制器的初始化甚至在它被链接之前就已经完成了。结果是一样的。
      【解决方案3】:

      我知道这是一个旧的,但我发现它是为了寻找答案,虽然我没有得到它,但我确实更新了你的 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();
      
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-27
        相关资源
        最近更新 更多