如何使指令具有每个用途的唯一范围项

时间:2014-08-05 23:58:15

标签: angularjs angularjs-directive

我已经创建了一个指令并用它来制作两个时间计数器但是我对如何为每个时间计数器使用不同的范围项目感到有点困惑。

我做了一个Plunkr来说明。

我不确定是否应该将范围项添加到mainCtrl控制器或指令范围。如果我将它添加到指令范围,那么如何将mainCtrl分开,以便以后可以保存?希望吸收者更清楚一点。

3 个答案:

答案 0 :(得分:1)

虽然@MarkM建议有效,但我建议添加scope: {},因为它更符合Angular的实施:

app.directive('time', function () {
    return {
      templateUrl: 'time.html',
      scope: {},
      restrict: 'E',
      link: function (scope, element, attrs) {
        element.addClass('time');
        // $compile(element)(scope);
      }
    };
  });

答案 1 :(得分:1)

您需要声明一个隔离范围,以在指令范围内定义一个属性,该属性与父范围上的属性双向绑定。

例如,您的指令代码应为:

app.directive('time', function() {
  return {
    templateUrl: 'time.html',
    restrict: 'E',
    scope: {
      Time: '=value'
    },
    link: function(scope, element, attrs) {
      element.addClass('time');
    }
  };
});

相关标记变为:

  <h1>Times</h1>
  <strong>Timer 1</strong> – I would like this to use the 'Time' scope item
  <br>
  <time value="Time"></time>
  <br>
  <br>
  <strong>Timer 2</strong> – I would like this to use the 'altTime' scope item
  <br>
  <time value="altTime"></time>

查看我的forked Plunkr

编辑:还有一些评论:

  • 命名属性的一般JS约定是使用camelCasingPascalCase保留用作JS等价类的函数(即应该使用new运算符调用的函数)
  • 你在原始的plunkr中输入了一个拼写错误,你将初始范围属性声明为alTime,但在标记中引用了altTime(我的Plunkr修复此问题)。
  • 在指令中进行双向绑定的是=运算符。有关详细信息,请参阅Angular docs
  • 在这种情况下,您不需要使用ng-model来指向该值。你理论上可能,但它会更难做,我不相信在这种情况下是必要的。只需使用我所描述的隔离范围绑定。
  • 请记住我认为的 AngularJS黄金法则:&#34;在ng-model表达式中总是有一个点(。),除非你有充分的理由省略它&#34;这意味着您始终在正确的范围内设置对象的属性,即使该范围是层次结构中的多个级别。例如,在您的代码中,使用ng-click="Time = Time + 1"指令实际上会让您在指令的范围上创建新属性Time,即使属性最初存在于父范围内。

    注意我在我的Plunkr中违反了这个规则,但那是因为我知道隔离范围将具有不同的Time属性到父范围的Time属性,并且AngularJS通过在隔离范围上使用=说明符来保持两个同步。

答案 2 :(得分:0)

您只需将scope:true添加到您的指令即可。这是一个分叉的Plunkr。它将创建一个应该从封闭元素的范围继承的新范围。