将 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-class
docs.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/JSONobjects
输出为 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
定义为<style>
标记的范围,因为<style>
标记应在<head>
中,而ng-controller
通常定义在<body>
标记或以下。 TL;DR: 将您的 ng-controller
放在您的 <html>
标签上,如下所示:
<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 是 .$eval
uated 作为其中插入变量的字符串),还需要处理 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 1.7.9 从控制器到组件的绑定变量提供未定义的值