将 AngularJS 变量绑定到 CSS 语法中

Posted

技术标签:

【中文标题】将 AngularJS 变量绑定到 CSS 语法中【英文标题】:Bind AngularJS variables into CSS syntax 【发布时间】:2013-08-17 09:23:57 【问题描述】:

我试图弄清楚如何将 AngularJS 范围变量绑定到 CSS 语法中。 我认为问题出在花括号中。 这就是我基本上想要做的事情:

<style>.css_class background: angular_variable ; color:#ffffff;</style>
<style>.css_rule background: "#000000" ; color:#ffffff;</style>
<style>.css_rule background: var | someFilter ; color:#ffffff;</style>

关于如何实现这一点的任何想法? 谢谢!

【问题讨论】:

你检查ng-classdocs.angularjs.org/api/ng.directive:ngClass。这段代码在哪里? 是的,我知道 ng-class,但我需要操作非 dom 元素,例如 ::-webkit-scrollbar ... css 代码在 html 视图中(在控制器范围内)跨度> 【参考方案1】:

正如here 解释的那样,角度不会在样式标签内的内容上运行。该帖子中有一个解决方法 plunkr,但作为一种更灵活的方法,我只需创建一个指令来获取内容,解析它们并替换:

更新答案

app.directive('parseStyle', function($interpolate) 
    return function(scope, elem) 
        var exp = $interpolate(elem.html()),
            watchFunc = function ()  return exp(scope); ;

        scope.$watch(watchFunc, function (html) 
            elem.html(html);
        );
    ;
);

用法:

<style parse-style>.css_class color:  angular_variable ;</style>

http://jsfiddle.net/VUeGG/31/


原答案

app.directive('parseStyle', function()

    return function(scope, elem)
    
        elem.html(scope.$eval('\'' + elem.html() + '\''));
    ;
);

然后:

<style parse-style>.css_class color: ' + angular_variable + ';</style>

不确定浏览器对此的支持。

http://jsfiddle.net/VUeGG/4/

【讨论】:

我刚刚在下面添加了这个很棒的代码的主要重构。感谢您的启发! @Campbeln 这是正确的想法,但您可以使用 $interpolate 来取消解析。事实上,我不知道为什么我一开始没有使用它。查看更新的答案 我已经使用它并运行它,结果是一个 Angular “插件”(模块+过滤器+工厂)called ngCss 可以处理这个以及更多 - check it out! @jonnyynnoj 这是一个很好的答案,有没有办法轻松地将其调整为内联脚本?例如,我尝试了 但这会返回 angular_variable @jonnyynnoj 如果我试图列出几个具有相同类但需要为其中一个 CSS 属性(例如 background-color)具有不同值的项目,这仍然有效吗?【参考方案2】:

更新

我已经组合了一个 Angular“插件”(模块+过滤器+工厂)called ngCss 来处理这个以及更多 - check it out!

我还制作了 Vanilla javascript(例如,没有外部依赖项)版本; CjsSS.js (GitHub)。

ngCss 是一个微小的* Angular Module+Factory+Filters,可以在 CSS 中绑定字符串和对象(包括嵌套对象)。 *1700字节以下的缩小+压缩脚本

特点:

CSS 可以是实时绑定的($scope 中的更改是 $watch'ed)或通过自定义 $broadcast 事件 updateCss 更新。 css 和 cssInline 过滤器将 Javascript/JSON objects 输出为 CSS 以启用 mixins,包括嵌套 objects 的能力。 $scope 可以在 CSS 本身中初始化,允许所有与 CSS 相关的信息位于 *.css 或 STYLE 元素中。 $scope 可以从任何 Angular $element 隔离或导入(通过angular.element($element).scope())。

原创 感谢@jonnyynnoj 的代码,我找到了一种将angular_variable 命名法保留在样式标签中以及实时绑定任何更改的方法。 Check out the fork of @jonnyynnoj's code 是一个简单的例子,或者看看下面我在我的应用程序中使用的内容:

(function (ngApp) 
    'use strict';

    //# Live bind a <style cn-styler=" commented: true, usingSingleQuote: true " /> tag with ngVars
    ngApp.directive('cnStyler', function () 
        return 
            //# .restrict the directive to attribute only (e.g.: <style cn-styler>...</style>)
            restrict: "A",
            link: function ($scope, $element, $attrs, controllers) 
                //# .$eval the in-line .options and setup the updateCSS function
                //#     NOTE: The expected string value of the inline options specifies a JSON/JavaScript object, hence the `|| ` logic
                var css, regEx,
                    options = $scope.$eval($attrs["cnStyler"]) || ,
                    updateCSS = function () 
                        //# .$eval the css, replacing the results back into our $element's .html
                        $element.html($scope.$eval(css));
                    
                ;

                //# Setup the .quote and the inverse in .unquote (which we use to process the css)
                //#     NOTE: In theory, the .unquote should not be present within the css
                options.quote = (options.usingSingleQuote !== false ? "'" : '"');
                options.unquote = (options.quote === '"' ? "'" : '"');
                regEx = new RegExp(options.unquote, "g");

                //# Process the $element's .html into css, .replace'ing any present .unquote's with .quote's (this could cause problems), then the Angular (or /*Angular*/) variables with ' + stringified_versions + '
                if (options.commented !== false) 
                    css = options.unquote + ($element.html() + '')
                        .replace(regEx, options.quote)
                        .replace(/\/\*/g, options.unquote + "+")
                        .replace(/\*\//g, "+" + options.unquote)
                    + options.unquote;
                 else 
                    css = options.unquote + ($element.html() + '')
                        .replace(regEx, options.quote)
                        .replace(//g, options.unquote + "+")
                        .replace(//g, "+" + options.unquote)
                    + options.unquote;
                

                //# .$watch for any changes in the $scope, calling our updateCSS function when they occur
                $scope.$watch(updateCSS);
            
        ;
    );

)(YOUR_NG_APP_VAR_HERE);

然后你像这样使用这个指令:

<style cn-styler type="text/css">
    .myClass
        color: /*themeColor*/;
    
</style>

您在控制器中的某处设置了$scope.themeColor,并且您已将YOUR_NG_APP_VAR_HERE 替换为您的ngApp 变量。

注意事项:

确保您的ng-controller 定义为&lt;style&gt; 标记的范围,因为&lt;style&gt; 标记应在&lt;head&gt; 中,而ng-controller 通常定义在&lt;body&gt; 标记或以下。 TL;DR: 将您的 ng-controller 放在您的 &lt;html&gt; 标签上,如下所示:

<html ng-app="YOUR_NG_APP_VAR_HERE" ng-controller="MyNgController">

由于 Visual Studio 等工具中的 CSS 解析和自动格式化,我添加了在 CSS cmets 中包含 Angular 变量的功能(例如 /*Angular*/)。 这是指令的默认行为,除非您像这样覆盖它:

<style cn-styler="commented: false" >...</style>

由于此解决方案的性质(CSS 是 .$evaluated 作为其中插入变量的字符串),还需要处理 CSS 中存在的单引号或双引号。默认情况下,该指令假定您在 CSS 中使用单引号 ('),这意味着为了避免任何引入的错误 您应该只在 CSS 中使用单引号,因为 CSS 中存在任何双引号将替换为单引号。您可以像这样覆盖此默认行为(意味着您在 CSS 中使用双引号):

<style cn-styler="usingSingleQuote: false" >...</style>

在某些极端情况下,用单引号替换双引号会破坏 CSS(例如在 content 中),因此您需要确保在 CSS 中仅使用一种样式的引号(并发出信号相应的指令)以避免任何潜在问题。谢天谢地,CSS 中很少使用引号,所以这基本上不是问题。

【讨论】:

支持我的 html 中缺少的第一个注释,样式是在控制器上方定义的。非常感谢。【参考方案3】:

我不明白你为什么要使用这个想法! 你应该为此使用 ng-class!

例如:

<p ng-class="strike: strike, bold: bold, red: red">Map Senter code hereyntax Example</p>

【讨论】:

因为我需要使用来自外部源的颜色来操作滚动条等非 dom 元素【参考方案4】:

你不应该需要花括号,因为它们是在 html 指令中计算的 - 如果你有一个在它们之外计算的表达式,你只需要使用花括号;

<p ng-class="some-angular-variable">
  some-angular-variable
</p> 

在您的情况下,删除双花括号并使用双引号应该可以解决问题。

顺便说一句,Chandermani 是在赚钱 - 使用 ng-class 指令可以更好地完成您想要做的事情。使用它将允许将一个(或多个)类应用于相应的标签。

即;

<p ng-class="mystyle">
    some text
</p>

假设你有两个类 style1 和 style2

你可以选择任何一个来申请

scope.mystyle = "style1" // or whatever

在您的控制器中。

【讨论】:

我需要应用稍后会出现的“未知”颜色..所以类在这里不相关..另外,我不能将 ng-class / ng-style 属性应用于非 dom 元素像 ::-webkit-scrollbar

以上是关于将 AngularJS 变量绑定到 CSS 语法中的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS

如何查看angularjs版本

AngularJS 1.7.9 从控制器到组件的绑定变量提供未定义的值

AngularJS过滤器模板绑定语法 - 不像docs?

AngularJS语法基础及数据绑定——详解各种数据绑定指令属性应用

AngularJS 框架