css类在更改nativeElement.className后未生效

hzbexzde  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(154)

所以我在写一个有Angular 的应用程序,我试图重新设计一个垫子形式的领域。
超文本:

<mat-form-field  #matFormField class="example-full-width" >
     <input #autocompleteInput type="text" placeholder="Enter {{searchBy.value}}" aria-label="Number" matInput [formControl]="myControl"
         [matAutocomplete]="auto"  (keyup.enter)="onEnter()">
     <fa-icon  [icon]="faSearch"></fa-icon>
     <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
         <mat-option *ngFor="let option of autocompleteList" [value]="option" (onSelectionChange)="autocompleteSelected($event)">
             {{option[searchBy.value]}}
         </mat-option>
     </mat-autocomplete>
</mat-form-field>

typescript :

@ViewChild('matFormField', { static: false, read: ElementRef}) formField: ElementRef;

ngAfterViewInit(): void {
  this.formField.nativeElement.children[0].children[0].children[0].className = 'mat-form-field-infix-fix';
}

SCSS:

mat-form-field {
  width: 100%;
}

.mat-form-field-infix-fix {
  display: flex;
  position: relative;
  flex: auto;
  min-width: 0;
}

fa-icon {
  float: right;
}

我可以看到className确实被应用了:

但由于某些原因CSS不是

有人知道这是怎么回事吗?

omqzjyyz

omqzjyyz1#

我相信您正在遇到here讨论的视图封装。
如前所述,组件CSS样式封装在组件的视图中,不会影响应用程序的其余部分。
以及前面在样式范围部分中的讨论:
@Component元数据中指定的样式仅应用于该组件的模板中。
模板中嵌套的任何组件都不会继承它们,投影到组件中的任何内容也不会继承它们。
因此,要让css实现嵌套组件样式,您有以下几种选择:
1.更改视图封装设置
1.将此样式设置放在应用程序的全局样式表中
1.在组件的css中,使用特殊的piercing rules,例如::ng-deep(有用,但是Angular团队已经弃用这些,没有提供好的替代方案)

w8rqjzmb

w8rqjzmb2#

Encapsulation将是此问题的直接原因。
检查组件的decorator是否进行封装,这将更改默认的CSS策略:
ViewEncapsulation。Emulated(默认值)Angular用于修改组件的CSS选择器,使其仅应用于组件的视图,而不影响应用程序中的其他元素,从而模拟Shadow DOM行为。有关更多详细信息,请参见检查生成的CSS。
在Angular中,不要使用document方法来处理DOM。
1.使用ElementRef访问DOM,但从不更新DOM。
1.使用Renderer2访问和/或更新DOM。
我对此事的笔记(希望这对某人有帮助)

// document methods vs Renderer2 and ElementRef
constructor( private eRef: ElementRef, private renderer: Renderer2){  }

// let elem = document.createElement('div');
let elem = this.renderer.createElement("div") as HTMLDivElement;
// or Angular's template ids <div #elem>
@ViewChild('elem', { static: true }) elem!: ElementRef;

// check for classnames
this.elm.nativeElement.classList.contains('className');

// elem.classList.add('class-name');
this.renderer.addClass(this.eRef, 'class-name');

// elem.classList.remove('class-name');
this.renderer.removeClass(this.eRef, className);

// elem.setAttribute('class', 'class-name'); // to add the class attribute and add a single class, removes others
// if you need to set a property or an attribute whose name is not statically known, use the renderer.setProperty() or renderer.setAttribute() method.
this.renderer.setProperty(this.eRef, 'innerHTML', '<h1>Hello world</h1>');

this.renderer.setAttribute(this.eRef, 'height', '501px');

// elem.style.color = 'white';
this.renderer.setStyle(this.eRef, 'color', 'white');

// elem.appendChild(line);
this.renderer.appendChild(this.eRef, elem); // add the element to the DOM

// this.elem.classList.contains(class); // test for a classname on an element
// this.elem.parentNode.removeChild(span); // remove the element with native JS
// (<Element>this.elem.parentNode).classList.add('active'); // force TS to see element type (not a node)
// (<Element>this.elem.parentNode).classList.remove('active');

相关问题