简体   繁体   English

ngClass何时评估函数/如何在自定义指令中模仿

[英]When does ngClass evaluate functions / How to mimic this in custom directive

I'm hoping someone can offer some Angular insight that I am sorely lacking right now. 我希望有人可以提供一些我现在非常缺乏的Angular见解。

ngClass allows you to add/remove a class depending on some function. ngClass允许您根据某些功能添加/删除类。 For example, if I write: 例如,如果我写:

<div ng-class="{'some-class' : myFunction()}"> </div>

then .some-class will be added/removed if myFunction() evaluates to truthy or falsey. 如果myFunction()评估为true或false,则将添加/删除.some-class。 What is especially good is that I don't need to worry about this function getting called anywhere else in my code for the expression to evaluate. 特别好的是,我不必担心此函数在代码中的其他位置被调用以求表达式进行计算。 ngClass just takes care of keeping the class up to date with the current return value of myFunction(). ngClass只是负责保持类与myFunction()的当前返回值保持最新。

So my first question is how does ngClass determine when to check if the return value of myFunction() has changed? 所以我的第一个问题是ngClass如何确定何时检查myFunction()的返回值是否已更改? Does it check myFunction() on every digest loop? 是否在每个摘要循环上检查myFunction()? Something presumably has had a watch set on it, but what is being watched? 大概有东西放在上面了,但是正在看什么呢? I tried reading the code for ngClass but I didn't have enough background knowledge to get a handle on how it's implemented. 我尝试阅读ngClass的代码,但是我没有足够的背景知识来了解如何实现它。

The reason I want to know this is that I want to mimic this behaviour in a custom directive. 我想知道的原因是我想在自定义指令中模仿此行为。 So in my app I have something like the above ngClass. 所以在我的应用程序中,我有类似上面的ngClass的内容。 myFunction() is sitting on the main controller for my page, but it does a bunch of direct DOM manipulation so it shouldn't be there. myFunction()位于页面的主控制器上,但是它会进行大量直接的DOM操作,因此不应存在。 I'd like to take myFunction() out of the controller and move it into a custom directive, but if I do that then I need some way to repeatedly check against this function in order to set classes. 我想将myFunction()移出控制器,并将其移入自定义指令,但是如果这样做,则需要某种方式来反复检查该函数以设置类。 I would like to be able to do something like this: 我希望能够做这样的事情:

app.directive('myDirective', function () {
  return {
    restrict: 'A,
    link: function (scope, elem, attrs) {
      function myFunction() {//...}

      // I want this to be checked at the
      // same frequency that ngClass is checked
      // Is that each digest cycle?

      if (myFunction()) {
        elem.addClass('some-class');
      } else {
        elem.removeClass('some-class');
      }
    }
  }

Obviously this isn't going to work. 显然,这是行不通的。 It's only going to run when the directive gets linked. 它仅在链接指令时运行。 So how can I watch myFunction() for changes? 那么,如何查看myFunction()的更改?

I would use .$watch() , which evaluates the initial argument during every $digest cycle, and invokes a listener (the second argument) once during initial load and subsequently, every time the evaluation of the initial argument returns a different value than the previous. 我将使用.$watch() ,它会在每个$ digest周期内评估初始参数,并在初始加载期间调用一次侦听器(第二个参数),随后,每次初始参数的评估返回与以前。

See https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch . 参见https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

Base on the psuedo-code you provided (actual code would have been nicer for testing purposes :-) here's an example of what you should do: 根据您提供的伪代码(出于测试目的,实际代码会更好:-)这是您应做的示例:

app.directive('myDirective', function () {
  return {
    restrict: 'A',
    link: function (scope, elem, attrs) {
      scope.$watch(function() {
         // .. this is your "myFunction()"
         return result;
      }, function(newResult) {
        if (newResult) {
          elem.addClass('some-class');
        } else {
          elem.removeClass('some-class');
        }
      });
    }
  }
}  

Also, make sure you have the closing quote on the 'A' value. 另外,请确保您在“ A”值上加上了结束语。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM