【问题标题】:CSS bootstrap not working in Angular sub componentCSS bootstrap 在 Angular 子组件中不起作用
【发布时间】:2020-02-29 00:26:43
【问题描述】:

在 Angular 8 的父组件中包含我的子组件时遇到问题。我的子组件仅包含一个下拉菜单。现在,当我在父组件中包含相同的内容以及在父组件的 div 中使用的 CSS 时,显示输出将按预期进行。

父组件:

<div class="col-lg-12">
  <div class="form-group row">
    <label class="col-sm-1 col-form-label-lg font-weight-bold">Country</label>
    <div class="col-sm-5">
      <app-country >
      </app-country>
    </div>
  </div>
</div>

子组件

<select [(ngModel)]='countryDetails.default' class="form-control form-control-lg">
  <option *ngFor="let province of countryDetails.details" value={{country.id}}>
    {{country.value}}
  </option>
</select>

但现在为了减少编码计划在子组件中移动 div class="col-sm-5"。

新编码不起作用:

父组件:

 <div class="col-lg-12">
      <div class="form-group row">
        <label class="col-sm-1 col-form-label-lg font-weight-bold">Country</label>
        <app-country></app-country>
      </div>
    </div>

子组件:

<div class="col-sm-5">
  <select [(ngModel)]='countryDetails.default' class="form-control form-control-lg">
    <option *ngFor="let province of countryDetails.details" value={{country.id}}>
      {{country.value}}
    </option>
  </select>
</div>

在第二部分中,如果我通过 Web 控制台扩展输出 HTML,然后发现 CSS 包含在代码中,但行为不同。

另外,请注意我使用的是引导 CSS。

任何帮助都将不胜感激。

【问题讨论】:

  • 您是仅使用 Bootstrap CSS 还是还包含了 Bootstrap 的 JS?
  • option循环中,是country.id还是province.id(和province.value)?
  • 将其作为国家 ID 或国家详细信息。这只是一个演示数据,供参考。另请注意,不包括 Bootstrap 的 JS。
  • @Souvik 为您的子组件使用属性选择器,请参阅我的答案

标签: html css angular


【解决方案1】:

如果您使用的是早期版本的 Angular,则封装默认设置是不同的。你可以试试

@Component({
    // ...
    encapsulation: ViewEncapsulation.None
})

用于 .ts 文件中的子组件。

【讨论】:

    【解决方案2】:

    是因为现在最后生成的HTML是这样的,

    <div class="col-lg-12">
          <div class="form-group row">
            <label class="col-sm-1 col-form-label-lg font-weight-bold">Country</label>
             <app-country>
               <div class="col-sm-5">
                    <select [(ngModel)]='countryDetails.default' class="form-control form-control-lg">
                      <option *ngFor="let province of countryDetails.details" value= 
                      {{country.id}}>
                      {{country.value}}
                      </option>
                    </select>
                 </div>
            </app-country>
          </div>
     </div>
    

    但更早,

        <div class="col-lg-12">
          <div class="form-group row">
            <label class="col-sm-1 col-form-label-lg font-weight-bold">Country</label>
               <div class="col-sm-5">
                  <app-country>
                      <select [(ngModel)]='countryDetails.default' class="form-control form-control-lg">
                         <option *ngFor="let province of countryDetails.details" value= 
                           {{country.id}}>
                           {{country.value}}
                         </option>
                       </select>
                  </app-country>
               </div>
          </div>
     </div>
    

    如您所见,&lt;app-country&gt; 的位置与您的方法不同。在col-sm-5 之前和col-sm-5 之后

    这会导致 Bootstrap row 类破坏 css :)

    【讨论】:

      【解决方案3】:

      更新:解决方案 2

      引用自https://stackoverflow.com/a/52717242/5061139

      您可以创建directive,然后动态删除父元素。

      @Directive({
         selector: '[remove-wrapper]'
      })
      
      export class RemoveWrapperDirective {
         constructor(private el: ElementRef) {
           const parentElement = el.nativeElement.parentElement;
           const element = el.nativeElement;
           parentElement.removeChild(element);
           if(parentElement.parentNode){
             parentElement.parentNode.insertBefore(element, parentElement.nextSibling);
             parentElement.parentNode.removeChild(parentElement);
           }
         }
      }
      

      并像这样使用它,

      <div class="col-lg-12">
        <div class="form-group row">
          <label class="col-sm-1 col-form-label-lg font-weight-bold">Country</label>
          <app-country></app-country>
        </div>
      </div>
      

      还有像这样的子组件:

      <div class="col-sm-5" remove-wrapper>
        <select [(ngModel)]='countryDetails.default' class="form-control form-control-lg">
          <option *ngFor="let province of countryDetails.details" value= . {{country.id}}>
            {{country.value}}
          </option>
        </select>
      </div>
      

      这将满足您的要求。

      -->

      因此,您的方法的问题是,当您的子组件在 DOM 中呈现时,它有一个额外的元素包装器。因此,呈现的 HTML 就像

      <div class="col-lg-12">
        <div class="form-group row">
          <label class="col-sm-1 col-form-label-lg font-weight-bold">Country</label>
           <app-country>
             <div class="col-sm-5">
                  <select [(ngModel)]='countryDetails.default' class="form-control form-control-lg">
                    <option *ngFor="let province of countryDetails.details" value= 
                    {{country.id}}>
                    {{country.value}}
                    </option>
                  </select>
               </div>
          </app-country>
        </div>
      

      如您所见,HTML 中有额外的 &lt;app-country&gt;&lt;/app-country&gt; 包装器。要解决这个问题,您可以将attribute selector 用于您的子组件。

      @Component({
        selector: '[app-country]',
        template:  './app-country.component.html',
        styleUrls: ['./app-country.component.css']
      })
      

      在你的父组件中使用它:

      <div class="col-lg-12">
        <div class="form-group row">
          <label class="col-sm-1 col-form-label-lg font-weight-bold">Country</label>
          <div class="col-sm-5" app-country>
          </div>
        </div>
      </div>
      

      现在,您不会得到任何额外的元素包装器,并且您的引导 css 可以正常工作。希望这将有助于解决您的问题。

      【讨论】:

      • 我正在尝试将总 div 移动到我的子组件中。因为无论在何处导入此组件,都将具有相同的列大小和详细信息。我的目的是在导入时减少代码。
      • @Souvik 我已经更新了答案并为您的情况提出了另一种解决方案
      • 嘿,这解决了我最初的下拉 CSS 问题,但由于标签相同,我如何在组件中移动标签。使用此代码,如果我将其放入组件中,它将删除标签。
      【解决方案4】:

      @ankit-agarwal 的回答是相关的。 尽管如此,如果你想强制类 col-sm-5 到你的组件,在它里面,你应该使用HostBindingHostBinding 允许您将属性/类/样式附加到托管组件或指令的 Dom 元素。

      因此,在您的示例中,您需要保留 app-country 选择器(我不太喜欢组件的属性选择器):

      /* country.component.css */
      /* This is necessary in order to have the app-country element behave as a
       * div in the page layout. */
      :host {
        display: block;
      }
      
      <!-- country.component.html -->
      <!-- you don't need the div, because we are going to attach the class
           to the app-country tag itself. -->
      <select [(ngModel)]='countryDetails.default' class="form-control form-control-lg">
        <option *ngFor="let province of countryDetails.details" value={{country.id}}>
          {{country.value}}
        </option>
      </select>
      
      @Component({
        selector: 'app-country',
        ...
      })
      export class CountryComponent {
        @HostBinding('class.col-sm-5') cssWidthClass = true;
      }
      

      true 将指示 Angular 在宿主标签 (app-country) 中的类列表中输出 col-sm-5 类。
      您可以有一个额外的 Input 属性用于将cssWidthClass 字段(顺便说一下,名称并不重要)设置为null,以便输出col-sm-5 类,如果需要。

      【讨论】:

      • 这个解决方案也适用于我。但是你能告诉我如何在组件下添加标签吗?
      【解决方案5】:

      @Souvik,您需要先安装引导程序,并且需要在“angular.json”中提供引导程序文件的链接。

      以下是在 Angular 项目中使用 bootstrap 的方法,希望对你有用。

      方法 1:使用 Angular CLI (npm install)。

      要在您的项目中安装引导程序,您可以使用以下命令

      npm install bootstrap --save
      

      之后,您需要将其添加到位于项目根目录的“angular.json”文件中

      "styles": [
      
                    "node_modules/bootstrap/dist/css/bootstrap.min.css",
                    "src/styles.scss"
                ],
      

      添加后你需要关闭并运行你的项目一次,这样它才能正常工作

      方法 2:使用 CDN(复制和粘贴方法)。 您可以使用旧的方式在项目中使用引导程序,将路径的 URL 添加到 index.html 以供全局引用。

      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      

      方法 3:将引导 CSS 文件添加到您的项目(使用 CSS 导入): 您可以直接将引导文件夹添加到 Angular 项目中的资产目录中,并使用

      将该文件夹直接引用到您的 style.css 或 style.scss
      @import url("bootstrap.min.css"); 
      

      【讨论】:

        【解决方案6】:

        您的子组件将在父组件标签内呈现(如下所示)。

         <app-country>
        <div class="col-sm-5">
          ...
        </div>
        </app-country>
        

        所以相应地修改你的css或者使用父组件中的属性选择器

        eg. <div class="col-sm-5" app-country></div>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-02-20
          • 2018-09-27
          • 2019-03-29
          • 1970-01-01
          • 1970-01-01
          • 2018-01-28
          • 1970-01-01
          相关资源
          最近更新 更多