動態

詳情 返回 返回

Angular的無選擇器(Selectorless)非官方實現 - 動態 詳情

Angular的無選擇器(Selectorless)非官方實現

  • 眾所周知,Angular的組件定義,使用的時候,必須生成一個自定義標籤;某些時候使用css佈局的時候,就會比較麻煩
  • 雖然官方已經開始考慮實現無選擇器,但是目前還在規劃中,不知道要等多久

原理

  • 眾所周知,結構型指令可以動態插入模板
  • 模板內容可以自定義,並且也可以使用組件內的所有屬性和方法
  • 那麼只需要將組件變成一個模板,即可實現
  • 變成的方法也很簡單,在組件的html中,套一層ng-template即可
  • 那麼現在有了模板,只需要考慮如何使用模板
  • 也非常簡單,動態創建組件,會返回組件的實例,通過實例就能拿到模板引用
  • 既然有了模板引用,那麼就可以使用viewContainerRef插入了
  • 由於插入的是模板,組件僅僅進行了創建,所以並沒有組件的選擇器被插入
  • 這也就實現了無選擇器組件

實現

  • 以下代碼僅做原理展示,更詳細的部分請到倉庫中查看
  • 指令
// 創建組件引用,僅存在於內存
this._componentRef = createComponent(this.selectlessOutlet(), {});
// 獲得實例化的組件,注意組件需要有templateRef來保存模板引用
const instance = this._componentRef.instance as {
  templateRef: Signal<TemplateRef<any>>;
};
// 在結構型指令中插入模板(類似ngIf ngFor)
this.#viewContainerRef.createEmbeddedView(instance.templateRef());
// 綁定生命週期
this.#appRef.attachView(this._componentRef.hostView);
this._componentRef.changeDetectorRef.detectChanges();
  • 無選擇器組件部分
<ng-template #templateRef> 123 </ng-template>
@Component({})
export class InsertComponent implements OnInit {
  public templateRef = viewChild.required('templateRef');
}
  • 調用部分
<ng-container *selectlessOutlet="InsertComponent;inputs:{}"> </ng-container>

限制

  • 當然,這個方法有一些侷限性
  • ng-content實現會非常複雜;需要使用ng-template引用做輸入變量代替
  • 部分指令可能會受限,因為使用此種方法實現的組件相當於一個空殼,獲取不到真正的元素

    因為此時ElementRef獲取到的元素未在dom中

更快的使用?

  • 皮影視圖目前已經支持了自定義的無選擇器組件定義,並且可以很方便的切換

    皮影可以視為ngx-formly的Pro plus版本,與ngx-formly有着類似的概念,但是支持邏輯更加清晰,更加安全,支持強類型,多框架等特性

最後

  • 如果您有其他問題,歡迎郵箱wszgrcy@gmail.com聯繫
  • 無選擇器代碼倉庫
  • 皮影視圖代碼倉庫
  • 演示視頻
user avatar dingtongya 頭像 zaotalk 頭像 user_2dx56kla 頭像 front_yue 頭像 linx 頭像 anchen_5c17815319fb5 頭像 huichangkudelingdai 頭像 youyoufei 頭像 yulong1992 頭像 lovecola 頭像 abc-x 頭像 milton 頭像
點贊 102 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.