我的应用程序中有一个颜色名称列表。

let colours = {
  mango: '#e59c09',
  midnight: '#1476a0'
};

我想扩展ngStyle指令以能够理解我的自定义颜色名称。我正在通过ngStyle指令decorating来执行此操作。但是,我在装饰器的编译功能方面遇到了艰巨的挑战。我可以访问元素的ngStyle属性,但是它以字符串形式出现(可以理解)。 JSON.parse()不适用于它,因为绑定(bind)一次等后,它并不总是有效的JSON字符串...

我只是想进入,遍历所有样式键,如果它包含color,我想检查该值-如果是上述自定义颜色之一,则用十六进制替换。

我似乎无法访问任何ngStyle内部函数,并且source code令人困惑且简短;似乎只是设置了CSS元素-$ parse在哪里工作?例如,当ng-style="{color: ctrl.textColor}"时-ngStyle源代码中没有任何东西可提取ctrl.textColour的值。我看错地方了吗?

无论如何,如何访问ng样式的键值,以便可以将自定义颜色更改为其十六进制代码?

到目前为止,这是我在装饰器中得到的:
$provide.decorator('ngStyleDirective', function($delegate) {

    let directive = $delegate[0];
    let link = directive.link;

    directive.compile = function(element, attrs) {

        // Expression here is a string property
        let expression = attrs.ngStyle;

        return function(scope, elem, attr) {

          // How do I iterate over and update style values here?

          // Run original function
          link.apply(this, arguments);

        }

      }

      return $delegate;

});

我尝试使用正则表达式提取模式等并检查元素,但是,这对我来说似乎是错误的解决方法,因为我随后必须手动更新字符串并将其传递给基本链接函数。

这是plnkr example

如果有更好的方法来做我想做的事情,请告诉我。

最佳答案



可以在compile函数中重写ngStyle属性:

directive.compile = function(element, attrs) {
  let expression = getExpressions(attrs.ngStyle);
  attrs.ngStyle = expression;

  return function(scope, elem, attr) {
    // Run original function
    link.apply(this, arguments);
  }
}

JSON.parse()

如果更新了HTML,则JSON.parse()可以使用,以便键用双引号引起来,这意味着ng-style属性需要用单引号定界(尽管如果确实需要,可以尝试转义双引号。 ..)
<p ng-style='{ "color": "#e59c09" }'>Hello {{name}}!</p>
<p ng-style='{ "padding": "20px 10px", "background-color": "#1476a0", "color": "#ddd" }'>It is dark here</p>

然后解析该字符串应产生一个有效的对象,并且Object.keys()可用于遍历键,以检查单词的颜色。如果键包含颜色,Array.indexOf可用于检查颜色数组中是否存在该值。如果它确实存在于数组中,则可以使用String.replace()替换变量的值(即颜色的键)。
function getExpressions(str) {
    var parsed = JSON.parse(str);
    Object.keys(parsed).forEach(function(key) {
        if (key.indexOf('color') > -1) {
            if (Object.keys(colours).indexOf(parsed[key]) > -1) {
                str = str.replace(parsed[key], colours[parsed[key]])
            }
         }
    });
    return str;
}

请参见下面的示例中演示的内容。顺便说一句,我不得不删除在函数getExpressions()中声明的未使用的变量颜色,因为它隐藏了对上面第3行Here is an updated plunker定义的变量的访问。

let app = angular.module('plunker', []);
let colours = {
  mango: '#e59c09',
  midnight: '#1476a0'
};
app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});
app.config(function($provide) {
  // Extract colour values from the string
  function getExpressions(str) {
    var parsed = JSON.parse(str);
    Object.keys(parsed).forEach(function(key) {
      if (key.indexOf('color') > -1) {
        if (Object.keys(colours).indexOf(parsed[key]) > -1) {
          str = str.replace(parsed[key], colours[parsed[key]])
        }
      }
    });
    return str;
  }

  $provide.decorator('ngStyleDirective', function($delegate) {
    let directive = $delegate[0];
    let link = directive.link;

    directive.compile = function(element, attrs) {
      let expression = getExpressions(attrs.ngStyle);
      attrs.ngStyle = expression;
      return function(scope, elem, attr) {
        // Run original function
        link.apply(this, arguments);
      }
    }
    return $delegate;
  });
});
div + div {
  margin-top: 60px;
}

.comment {
  font-family: courier;
  font-size: 12px;
  margin: 15px 0;
}
<script src="https://code.angularjs.org/1.4.12/angular.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
  <div>
    <p class="comment">--- with hex --</p>
    <p ng-style='{ "color": "#e59c09" }'>Hello {{name}}!</p>
    <p ng-style='{ "padding": "20px 10px", "background-color": "#1476a0", "color": "#ddd" }'>It is dark here</p>
  </div>

  <div>
    <p class="comment">--- with custom colours --</p>
    <p ng-style='{ "color": "mango" }'>Hello {{name}}!</p>
    <p ng-style='{ "padding": "20px 10px", "background-color": "midnight", "color": "#ddd" }'>It is dark here</p>
  </div>
</div>

关于javascript - 如何访问装饰器中的ngStyle键和值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44784294/

10-13 09:48