Angularjs 如何使指令在每次使用时都具有唯一的作用域项

Angularjs 如何使指令在每次使用时都具有唯一的作用域项,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我已经创建了一个指令,并使用它来创建两个时间计数器,但是我对如何为每个时间计数器使用不同的范围项感到有点困惑 我做了一个例子来说明 我不确定是否应将范围项添加到mainCtrl控制器或指令范围。如果我将其添加到指令范围中,那么如何将其与mainCtrl分开,以便以后保存?希望plunker更清晰一些。您可以在指令中添加范围:true。这是一个叉子。它将创建一个新的范围,该范围应继承封闭元素的范围。虽然@MarkM suggestion有效,但我建议添加范围:{},因为它更符合Angular的实现

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

我做了一个例子来说明


我不确定是否应将范围项添加到
mainCtrl
控制器或指令范围。如果我将其添加到指令范围中,那么如何将其与
mainCtrl
分开,以便以后保存?希望plunker更清晰一些。

您可以在指令中添加
范围:true
。这是一个叉子。它将创建一个新的范围,该范围应继承封闭元素的范围。

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

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

您需要声明一个隔离作用域来定义指令作用域上的属性,该属性与父作用域上的属性双向绑定

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

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>
计时器1–我希望它使用“时间”范围项



计时器2–我希望使用“altTime”范围项
看我的

编辑:更多评论:

  • 命名属性的一般JS约定是使用
    camelCasing
    ,而
    PascalCase
    保留用于充当类的JS等价物的函数(即,应该使用
    新的
    操作符调用的函数)
  • 您在原始plunkr中输入了一个错误,您将初始范围属性声明为
    alTime
    ,但在标记中引用了
    alTime
    (我的plunkr修复了这个问题)
  • 在指令中执行双向绑定的是
    =
    操作符。有关更多信息,请参阅
  • 在这种情况下,您不需要使用
    ng model
    来指向该值。理论上你可以,但这会更难做到,我认为在这种情况下没有必要这样做。只需使用我所描述的隔离作用域绑定
  • 请记住我认为盎格鲁JS的黄金法则:“在你的<代码> NG模型表达式中总是有一个点(除非)有一个很好的理由省略它。”这意味着你总是在正确的范围内设置一个对象的属性,即使该范围在层次结构中是几个级别的。例如,在您的代码中,使用
    ng click=“Time=Time+1”
    指令实际上会使您在指令的作用域上创建一个新属性
    Time
    ,即使该属性最初存在于父作用域上。

    注意,我在我的Plunkr中确实违反了这条规则,但这是因为我知道隔离作用域将有一个
    Time
    属性,该属性与父作用域的
    Time
    属性不同,并且AngularJS使用隔离作用域上的
    =
    说明符在封面下保持这两个属性的同步
这不起作用,因为它不会更新父作用域的属性,这是一项要求。请参阅您的解决方案的一部分,该解决方案添加文本以显示父作用域上的值,以证明该值未正确更新。您的回答有一半是正确的,但遗憾的是,您提供的解决方案不起作用。请看我的证明。作为解释,通过使用
scope:{}
声明,您正在创建一个隔离作用域,该作用域将无法访问原始
Time
属性,因此
timeFilter
显示“All”由于指令范围上的
时间
值是
未定义的
。这是官方最棒的答案!非常感谢您仔细检查了所有内容并花时间解释。一切都很完美,我明白为什么。赢