A solution for two-binding between angular and a style sheet

后端 未结 1 1117
长情又很酷
长情又很酷 2021-02-10 10:48

I know this sounds silly but I\'m writing a wysiwyg editor that allows Designers to create style guides. I\'ve become very fascinated with 2 way binding in angular and was curi

1条回答
  •  有刺的猬
    2021-02-10 11:26

    This was pretty fun to work on.

    You have access to all of the styles on a page through document.styleSheets, so you just need scope the rules on a style. So lets say that I have this class:

    .class {
        font-size: 20px;
        color: blue;
    }
    

    How jsfiddle implements sheets, this is the third style sheet added to the document, so I can just assign to the scope like this:

    myApp.controller('TestController', ['$scope', function ($scope) {
        $scope.styles = document.styleSheets[3].rules;     
    }]); 
    

    This would let you do things like $scope.styles[0].style['color'] = 'red' to change the color of anything with class to red. Since it's the first thing in the style array.

    But that's not cool enough, so we want to create a directive where we can change these from a ui. So we'd like to know all of the things that class controls, to create controls for them, So we can manipulate the css string to get all of those.

    Next we have to create a temporary scoped object on the directive that starts off with all of the styles. The reason is that style sheets have checking, so as you type into an input if you do something like $scope.styles[0].style['color'] = 'g' and it was red, it will just reset to red.

    So we create an input for each style type, with ng-model of our temp, then just listen for changes and attempt to assign to the style sheet.

    I created a fiddle where I implement it, but the directive looks like this.

    myApp.directive('styler', function() {
        return {
            scope: {
                styles: '='
            },
            restrict: 'EA',
            template: '
    {{type}}
    ', 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]; }; } }; });

    Cool, dynamic two way binding of styles!

    Hope this helped!

    0 讨论(0)
提交回复
热议问题