Javascript angular和样式表之间的两个绑定的解决方案

Javascript angular和样式表之间的两个绑定的解决方案,javascript,css,angularjs,gruntjs,Javascript,Css,Angularjs,Gruntjs,我知道这听起来很傻,但我正在编写一个wysiwyg编辑器,允许设计师创建样式指南。我对angular中的双向绑定非常着迷,并且好奇css表单和ng模型输入字段之间是否可以双向绑定。目前,我正在制作一个动态样式指南,允许设计师选择页面的主、辅颜色。这些颜色将统一地改变网站的整个主题,从样式表本身做到这一点将是非常棒的 HTML <input type="text" ng-model="color.primary" /> <button class="btn primary-col

我知道这听起来很傻,但我正在编写一个wysiwyg编辑器,允许设计师创建样式指南。我对angular中的双向绑定非常着迷,并且好奇css表单和
ng模型
输入字段之间是否可以双向绑定。目前,我正在制作一个动态样式指南,允许设计师选择页面的主、辅颜色。这些颜色将统一地改变网站的整个主题,从样式表本身做到这一点将是非常棒的

HTML

<input type="text" ng-model="color.primary" />
<button class="btn primary-color" />
js $scope.color{primary:'00f',secondary:'#e58'}

我知道有很多指令,比如
ng-style
ng-class
,但我担心每个标记都必须是一个指令,因为任何东西都可能有一个ng-style/ng-class标记。因此,我的代码不是很枯燥,很难维护


如果我想要css的动态样式指南呢。我可以将一张表作为CSS的键值对存储到firebase之类的服务器中,甚至可以实时绑定颜色的变化?我很确定这不能只用角度。。。有没有人对预编译器或黑客有什么想法来完成这项任务,从而产生一个干净风格的家伙?

这项工作非常有趣

您可以通过
document.styleSheets
访问页面上的所有样式,因此您只需确定样式上的规则范围。让我们假设我有一门课:

.class {
    font-size: 20px;
    color: blue;
}
JSFIDLE是如何实现工作表的,这是添加到文档中的第三个样式表,因此我可以这样分配给范围:

myApp.controller('TestController', ['$scope', function ($scope) {
    $scope.styles = document.styleSheets[3].rules;     
}]); 
这将允许您执行类似于
$scope.styles[0].style['color']='red'
的操作,以将任何具有类的对象的颜色更改为红色。因为这是样式数组中的第一件事

但这还不够酷,所以我们想创建一个指令,在这里我们可以从ui更改这些。所以我们想知道类控制的所有东西,为它们创建控件,这样我们就可以操纵css字符串来获得所有这些

接下来,我们必须在指令上创建一个临时作用域对象,该对象从所有样式开始。原因是样式表具有检查功能,因此,如果您执行类似于
$scope.styles[0].style['color']='g'
的操作并将其重置为红色,则当您键入输入时,它将被重置为红色

因此,我们使用temp的ng模型为每个样式类型创建一个输入,然后只需侦听更改并尝试分配给样式表

我在实现它的地方创建了一个指令,但该指令如下所示

myApp.directive('styler', function() {
    return {
        scope: {
            styles: '='
        },
        restrict: 'EA',
        template: '<div ng-repeat="type in types">{{type}} <input ng-change="Change(type)" ng-model="temp_styles[type]"/></div>',
        link: function(scope, elt, attrs) {      
            // get the actual styles
            var types = scope.styles.cssText.replace(/ /g, '').split('{')[1].split('}')[0].split(';');
            scope.types = [];
            scope.temp_styles = {};
            // get rid of "" element at the end
            types.pop();
            for (var i in types) {
                var split = types[i].split(':');
                scope.types.push(split[0]);
                scope.temp_styles[split[0]] = split[1];
            }
            scope.Change = function(type) {
                scope.styles.style[type] = scope.temp_styles[type];
            };
        }
    };
});
myApp.directive('styler',function(){
返回{
范围:{
样式:'='
},
限制:“EA”,
模板:“{type}}”,
链接:函数(范围、elt、属性){
//获取实际样式
var types=scope.styles.cssText.replace(//g',).split('{')[1]。split('}')[0]。split(';');
scope.types=[];
scope.temp_style={};
//最后去掉“”元素
type.pop();
for(类型中的变量i){
var split=types[i].split(“:”);
范围.types.push(拆分[0]);
scope.temp_样式[split[0]]=split[1];
}
scope.Change=函数(类型){
scope.styles.style[type]=scope.temp_styles[type];
};
}
};
});
酷,动态双向绑定的风格


希望这有帮助

只是随地吐痰,但也许你可以有一个服务,处理改变的风格。我试着做了一些搜索,但是看起来CSS文件并不能直接从Javascript访问,我猜使用jQuery选择器来获取基于类的元素,更新它们的样式是最好的选择。您可以在服务中实现它,并将其注入到一个指令中,然后可以在您希望使用.Hassassin中的模型的输入中使用该指令。。。好极了,我的人。。这太棒了。我已将其标记为正确,但您是否了解如何使用正则表达式或某种方法来定位样式的独立范围:“=”使用类的字符串而不是它的数组位置?我做了一个JSFIDLE练习,你可能会感兴趣。。。如果你想得到更多的分数,我可以提出一个新问题。总的来说,我认为最好是另一个问题,但因为这不是一个好答案,所以没关系。您可以在html中将类添加到styler并在链接函数中将其删除,也可以将其作为“@”传递给styler并循环遍历所有样式表并测试选择器文本。您的
文档。样式表[3]。规则
应该是
文档。样式表[3]。cssRules
。祝您好运,cssRules似乎是W3C标准。
myApp.directive('styler', function() {
    return {
        scope: {
            styles: '='
        },
        restrict: 'EA',
        template: '<div ng-repeat="type in types">{{type}} <input ng-change="Change(type)" ng-model="temp_styles[type]"/></div>',
        link: function(scope, elt, attrs) {      
            // get the actual styles
            var types = scope.styles.cssText.replace(/ /g, '').split('{')[1].split('}')[0].split(';');
            scope.types = [];
            scope.temp_styles = {};
            // get rid of "" element at the end
            types.pop();
            for (var i in types) {
                var split = types[i].split(':');
                scope.types.push(split[0]);
                scope.temp_styles[split[0]] = split[1];
            }
            scope.Change = function(type) {
                scope.styles.style[type] = scope.temp_styles[type];
            };
        }
    };
});