Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将css模块应用于AngularJS的更好方法_Javascript_Css_Angularjs_Css Modules - Fatal编程技术网

Javascript 将css模块应用于AngularJS的更好方法

Javascript 将css模块应用于AngularJS的更好方法,javascript,css,angularjs,css-modules,Javascript,Css,Angularjs,Css Modules,我现在正在使用带有AngularJS 1.5组件的css模块。堆栈是webpack+css加载程序?modules=true+angular 1.5组件+pug 目前,我必须执行以下步骤才能在我的pug模板中使用css模块 // my-component.js import template from 'my-component.pug'; import styles from 'my-component.css'; class MyComponent { constructor($

我现在正在使用带有AngularJS 1.5组件的css模块。堆栈是
webpack
+
css加载程序?modules=true
+
angular 1.5组件
+
pug

目前,我必须执行以下步骤才能在我的pug模板中使用css模块

// my-component.js

import template from 'my-component.pug';
import styles from 'my-component.css';

class MyComponent {
    constructor($element) {
        $element.addClass('myComponent');        // ------ (1)
        this.styles = styles;                    // ------ (2)
    }
}

angular.module(name, deps)
    .component('my-component', {
        controller: MyComponent,
        template: template,
    });

// my-component.pug
div(class={{ ::$ctrl.styles.fooBar }}) FooBar    // ----- (3)

// my-component.css
.myComponent { background: green; }
.fooBar { color: red; }
有两个问题:

  • 每个组件都必须注入
    $element
    ,并手动设置其类名。这样做的原因是,AngularJS组件标记本身存在于结果HTML中,没有任何类,这使得CSS很困难。例如,如果我像这样使用上面的
    MyComponent

    <div>
      <my-component></my-component>
    </div>
    
    // my-component.js
    angular.module(name, deps)
        .component('my-component', {
            controller: MyComponent,
            template: template,
            styles: styles,
        });
    
    // my-component.css
    div(css-class="fooBar") FooBar
    
    其想法是:

  • 使
    angular.module()并应用(1)
    $element.addClass()
  • 指令
    css类
    $ctrl.styles
    应用于元素

  • 我的问题是,我不知道如何实现上面的想法1(2很容易)。如果有人能分享一些关于这方面的信息,我将不胜感激。

    我想出了一个我不太满意的解决方案

    角度组件可以接受函数作为模板,并使用
    $element
    注入。

    如果模板是一个函数,则会向其注入以下局部变量:

    • $element-当前元素
    • $attrs-元素的当前属性对象
    因此,我们可以在模板函数中为component(
    .myComponent
    )附加主类,然后用已编译的类名替换所有出现的类名

    // utils.js
    function decorateTemplate(template, styles, className) {
        return ['$element', $element => {
            $element.addClass(styles[className]);
            return template.replace(/\$\{(\w+)\}/g, (match, p1) => styles[p1]);
        }];
    }
    
    // my-component.js
    import style from './my-component.css';
    import template from './my-component.pug';
    import { decorateTemplate } from 'shared/utils';
    
    class MyComponent {
        // NO NEED to inject $element in constructor
        // constructor($element) { ...
    }
    
    angular.module(name, deps)
        .component('myComponent', {
            // decorate the template with styles
            template: decorateTemplate(template, styles, 'myComponent'),
        });
    
    // my-component.pug, with special '${className}' notation
    div(class="${fooBar}") FooBar
    
    还有一个地方需要改进,
    decorateTemplate
    使用regex替换,模板必须使用特殊的符号
    ${className}
    来指定css模块的类名

    // utils.js
    function decorateTemplate(template, styles, className) {
        return ['$element', $element => {
            $element.addClass(styles[className]);
            return template.replace(/\$\{(\w+)\}/g, (match, p1) => styles[p1]);
        }];
    }
    
    // my-component.js
    import style from './my-component.css';
    import template from './my-component.pug';
    import { decorateTemplate } from 'shared/utils';
    
    class MyComponent {
        // NO NEED to inject $element in constructor
        // constructor($element) { ...
    }
    
    angular.module(name, deps)
        .component('myComponent', {
            // decorate the template with styles
            template: decorateTemplate(template, styles, 'myComponent'),
        });
    
    // my-component.pug, with special '${className}' notation
    div(class="${fooBar}") FooBar
    
    欢迎提出任何建议

    更新 我更新了我的
    decorateTemplate()
    函数以利用pug特性,这样本地类名就可以写成
    \u localClassName

    // utils.js
    function decorateTemplate(template, styles, className) {
    
        return ['$element', ($element) => {
            $element.addClass(styles[className]);
    
            return template.replace(/\sclass="(.+?)"/g, (match, p1) => {
                let classes = p1.split(/\s+/);
                classes = classes.map(className => {
                    if (className.startsWith('_')) {
                        let localClassName = className.slice(1);
                        if (styles[localClassName]) {
                            return styles[localClassName];
                        } else {
                            console.warn(`Warning: local class name ${className} not found`);
                            return className;
                        }
    
                    } else {
                        return className;
                    }
                });
                return ' class="' + classes.join(' ') + '"';
            });
        }];
    }
    
    // my-component.pug
    ._fooBar FooBar
    
    尽管这要容易得多,但它并没有消除奇怪的表示法(对于本地类名,以
    开头)和regex替换

    欢迎提出任何建议