【问题标题】:Angular & TailwindCSS - Dropdown menuAngular & TailwindCSS - 下拉菜单
【发布时间】:2021-03-06 20:31:49
【问题描述】:

抱歉,如果之前已经回答过这个问题,但我一直在寻找几天来找到答案,但我没有找到对我的设置有意义的解决方案(也许我的设置有误,让我们找出答案) .

我想使用带有 Tailwind CSS 的 Angular 创建一个下拉菜单,我的组件 html 如下:

// recipe-details.component.html
<div>
  <div *ngIf="selectedRecipe;else noRecipe">
    <div class="flex items-center justify-between">
      <h3 class="text-title">{{ selectedRecipe.name }}</h3>

      <!-- The dropdown menu -->
      <div class="relative">

        <!-- The dropdown button -->
        <a href="#" class="bg-green-500 px-3 py-2 rounded-md shadow font-bold text-white flex items-center" appDropdown>Manage recipe
          <svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"
            xmlns="http://www.w3.org/2000/svg">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
          </svg></a>

          <!-- Dropdown list of links -->
          <div class="origin-top-right absolute right-0 w-full rounded mt-2 shadow-lg border-gray-800">
            <div class="bg-white py-2">
              <a href="#" class="block px-4 py-2 font-bold text-sm text-gray-700 hover:bg-gray-100">Edit Recipe</a>
              <a href="#" class="block px-4 py-2 font-bold text-sm text-gray-700 hover:bg-gray-100">Delete Recipe</a>
            </div>
          </div>

      </div>

    </div>
    <p>{{ selectedRecipe.description }}</p>
  </div>

  <ng-template #noRecipe>
    <div class="">
      <div class="text-title ">Choose a recipe</div>
      <p>Please choose a recipe from the recipe list.</p>
    </div>
  </ng-template>
</div>

对于菜单按钮,我使用选择器 appDropdown 创建了一个指令:

//dropdown.directive.ts
import { Directive, EventEmitter, HostListener, Output } from '@angular/core';

@Directive({
  selector: '[appDropdown]'
})
export class DropdownDirective {
  @Output() isMenuOpen = new EventEmitter<boolean>();
  isOpen: boolean = false;

  constructor() { }

  @HostListener('click') toggleMenu() {
    this.isOpen = !this.isOpen;
    this.isMenuOpen.emit(this.isOpen);
    console.log(`Menu status changed. Menu is now ${this.isOpen ? 'Open' : 'Closed'}`)
  }

}

如果到目前为止我的想法是有意义的,那么在另一个指令中处理 EventEmitter 并将其放在 链接 div 的下拉列表中是否更有意义。无论isOpentrue 还是false,该指令将使用HostBinding 应用css 来设置opacity-0opacity-100 之间的div 的不透明度?

如果这种方法有效,我不确定如何从第二个指令中的第一个指令监听事件。

如果我完全不合时宜,有没有人可以帮助我理解工作流程的解决方案?

谢谢!

【问题讨论】:

    标签: javascript angular drop-down-menu dropdown tailwind-css


    【解决方案1】:

    我想以这种方式写下我的问题有助于我想出一个解决方案。如果有人有办法改进我的代码,请随时发布其他可以完成的方法:)

    我的解决方案:

    //recipe-detail.component.html
    <div>
      <div *ngIf="selectedRecipe;else noRecipe">
        <div class="flex items-center justify-between">
          <h3 class="text-title">{{ selectedRecipe.name }}</h3>
          <div class="relative">
            <a href="#" class="bg-green-500 px-3 py-2 rounded-md shadow font-bold text-white flex items-center" (isMenuOpen)=toggleVisible($event) appDropdown>Manage recipe
              <svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"
                xmlns="http://www.w3.org/2000/svg">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
              </svg></a>
              <div class="origin-top-right absolute right-0 w-full rounded mt-2 shadow-lg border-gray-800" [ngClass]="visibilityClasses">
                <div class="bg-white py-2">
                  <a href="#" class="block px-4 py-2 font-bold text-sm text-gray-700 hover:bg-gray-100">Edit Recipe</a>
                  <a href="#" class="block px-4 py-2 font-bold text-sm text-gray-700 hover:bg-gray-100">Delete Recipe</a>
                </div>
              </div>
          </div>
        </div>
        <p>{{ selectedRecipe.description }}</p>
      </div>
    
      <ng-template #noRecipe>
        <div class="">
          <div class="text-title ">Choose a recipe</div>
          <p>Please choose a recipe from the recipe list.</p>
        </div>
      </ng-template>
    </div>
    
    //recipe-detail.component.ts
    import { Component, OnInit } from '@angular/core';
    import { Recipe } from 'src/app/models/models.i';
    import { RecipeService } from '../../../services/recipes/recipe.service'
    
    @Component({
      selector: 'app-recipe-detail',
      templateUrl: './recipe-detail.component.html',
      styleUrls: ['./recipe-detail.component.scss']
    })
    export class RecipeDetailComponent implements OnInit {
      selectedRecipe: Recipe;
      visibilityClasses: {};
      private isVisible: boolean = false;
    
      constructor(private recipeService: RecipeService) { }
    
      ngOnInit(): void {
        this.recipeService.currentRecipe.subscribe(recipe => this.selectedRecipe = recipe
        );
        this.setVisibilityClasses();
      }
    
      toggleVisible(isVisible: boolean): void {
        console.log(`is the menu open: ${isVisible ? 'Yes' : 'No'}`)
        this.isVisible = isVisible;
        this.setVisibilityClasses();
      }
    
      private setVisibilityClasses(): void {
        this.visibilityClasses = {
          'opacity-0': !this.isVisible,
          'opacity-100': this.isVisible
        };
      }
    }
    
    //dropdown.directive.ts
    import { Directive, EventEmitter, HostListener, Output } from '@angular/core';
    
    @Directive({
      selector: '[appDropdown]'
    })
    export class DropdownDirective {
      @Output() isMenuOpen = new EventEmitter<boolean>();
      isOpen: boolean = false;
    
      constructor() { }
    
      @HostListener('click') toggleMenu() {
        this.isOpen = !this.isOpen;
        this.isMenuOpen.emit(this.isOpen);
        console.log(`Menu status changed. Menu is now ${this.isOpen ? 'Open' : 'Closed'}`)
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-09-07
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      相关资源
      最近更新 更多