为什么在指令中的相同值被同时定义和未定义?

时间:2014-09-29 10:21:51

标签: angularjs angularjs-directive angularjs-scope

为什么我将范围值视为未定义但已定义。

HTML

<body ng-app="plunker">
    <test-dir></test-dir>
</body>

JS

var app = angular.module('plunker', []);

app.directive('testDir', function($log) {
  return {
    restrict: 'E',
    template: 'My Dir',
    link: function(scope, element, arrts) {
      scope.test = scope.test || '2';
      $log.info(scope, scope.test);
    },
    scope: {
      test: "@test"
    }
  }
});

$logscope.test未定义scopescope.test scope.test显示test: "=?test"的奇怪是2?

enter image description here

我无法理解!

http://plnkr.co/edit/EU3llFTQYTEFgpKA5Y2Q?p=preview

如果我使用{{1}},这是有效的。但我不想要双向绑定,这不是让事情有效的问题。这是理解为什么相同的值在日志中显示不同的值的问题。

2 个答案:

答案 0 :(得分:1)

我认为你需要从你的html传递到你的孤立范围,如:

<test-dir test="true"></test-dir>

否则,您的隔离范围变量“test”未定义,每个摘要周期都将设置为undefined。

问题是你告诉AngularJS,通过代码将某些内容从父作用域传递到你指令的独立作用域:

scope: {
    test: "@test"
}

Angular会不断尝试将您隔离范围的值与父级的值匹配。

您可以完全删除 test:“@ test”,并且用户仍然可以更新它,但该值对指令外的任何其他范围都不可见。

BTW - @test会期望test是父作用域的一个函数 - 你可能想要= test如果你确实希望传递一些东西..

答案 1 :(得分:1)

这是因为初始化指令期间有2 $digest()个周期。 首先,您创建变量test并将其设置为'2'$digest()再次运行后,您的变量设置为不定义(从属性中读取)。

你可以观察到只是做一些小的黑客攻击:通过下一个方式包裹你的$log()函数:

setTimeout(function () {$log.info(scope, scope.test)}, 0);

现在,您将在控制台中看到您的test变量在范围和简单日志中都设置为undefined$log()功能将在$digest()完成工作后立即生效。

你可以做一个小技巧:

scope: {
  testA: "@test"
}

并在link函数中:

scope.test = scope.testA || '2';

因此,您可以看到您的test变量将始终设置为某个值。

演示:http://plnkr.co/edit/sywQKotOuX240VRYgz6Q?p=preview

相关问题