Angular Tracy 小笔记 Demo 项目

跟着项目走

项目结构

MVC 开发模式 : 三层结构 View视图层 .html,Control 逻辑处理层 .ts,Module 数据模型层 .ts

新建数据层 .ts 文件 如 recipes 下面手动创建的 recipe.module.ts
recipe.module.ts 数据模型,只在组件 recipes, recipe-list, recipe-item, recipe-detail 里能用到,所以我们把它放入 最外边的 recipes 文件夹中,像 ingredient.module.ts 数据模型所有自建控件都要用,那就在 app folder 下面新建 "share" folder
export class Recipe {
public name: string;
public description: string;
public imagePath: string;

constructor(name: string, desc: string, imagePath: string) {
//构造函数
this.name = name;
this.description = desc;
this.imagePath = imagePath;
}
}
上面的一大堆可以简化写为:
export class Recipe{
//注意这里的class 名开头字母要大写
constructor(public name: string, public description: string, public imagePath: string) {}
}

如何将 数据模型 recipe.module.ts 和组件 recipe 组件进行结合呢?
在 recipes-list.component.ts 里
引用 recipe.module.ts 文件里的 class 创建 recipe 对象: import { Recipe } from '../recipe.module';
Tips: 如果我们不知道怎么去算这个相对路径,那么就干脆这么写 import { Ingredient } from 'src/app/......XX.module';
recipes: Recipe[] = [
new Recipe( "name", "desc", "https://i.ytimg.com/vi/S4QsIz9eLdo/hqdefault.jpg?sqp=-oaymwEYCKgBEF5IVfKriqkDCwgBFQAAiEIYAXAB&rs=AOn4CLADbJI8vPDsx9RUrKlyd27mp46mYw" )
];

此时就可以在 recipes-list.component.ts 里调取数据了 {{recipes[0].name}}

父组件 recipe-list code, 此时它要把对象做一个循环将数据传递给子组件 recipe item:
<app-recipes-item *ngFor="let recipe of recipes; let i=index" [item]="recipe" [index]="i"></app-recipes-item>
这里的 recipes 是在 父组件里定义的数组

子组件 recipe item code
<div class="row" [ngStyle]="{backgroundColor: index%2 === 1? '#e0e0e0':'#eee'}">
<div class="col-4"><a href=""><img [src]="item.imagePath" class="img-fluid img-thumbnail mt-2"></a></div>
<div class="col-8 pt-2">
<p class="mb-0">名字:{{item.name}}</p>
<p>详情:{{item.description}} </p>
</div>
</div>
@Input() item;
@Input() index;

Tab 切换 Demo

  • header 选出来的值传递到根组件中 (header 和 另外两个组件是平级的):
    <li [ngClass]="{'nav-item': true, 'active': sellectTabName === 'recipe'}">
    <a class="nav-link" href="#" (click)="onSelect('recipe')">食谱</a> </li>
    <li [ngClass]="{'nav-item': true, 'active': sellectTabName === 'shopping-list'}">
    <a class="nav-link" href="#" (click)="onSelect('shopping-list')">商品</a> </li>

    import { Output, EventEmitter } from "@angular/core";
    @Output() featureSelected: EventEmitter<string> = new EventEmitter<string>(); sellectTabName:string = "recipe";
    onSelect(feature: string) {
    this.sellectTabName = feature;
    this.featureSelected.emit(feature);
    }
  • app 根组件接收值
    <app-header (featureSelected)="getFatherData($event)"></app-header>
    <app-shoping-list *ngIf="sellectTab === 'recipe'"></app-shoping-list>
    <app-recipes *ngIf="sellectTab === 'shopping-list'"></app-recipes>

    sellectTab: string = "recipe";
    getFatherData(msg: string) {
    this.sellectTab = msg;
    }

左边列表 list 点击列表其中一个item 右边显示详情 detail

  • item 里的 a 标签 加事件 (click)="selectOne()"
    import { Output, EventEmitter } from "@angular/core";
    @Output() selectItem: EventEmitter<void> = new EventEmitter<void>();
    selectOne() {
    this.selectItem.emit();
    }
    这里其实它的父组件已经知道它选的是 index 了,所以向上传值没啥意义,就做一个传值的动作就行了。
  • list 组件
    <app-recipe-item *ngFor="let recipeEL of recipes; let i=index" [item]="recipeEL" [index]="i" (selectItem)="onRecipeSelected(recipeEL)"></app-recipe-item>

    import { Output, EventEmitter } from "@angular/core";
    import { Recipe } from "../recipe.module";
    @Output() recipesWasSelected: EventEmitter<Recipe> = new EventEmitter<Recipe>();
    onRecipeSelected(item: Recipe) {
    this.recipesWasSelected.emit(item);
    }

    这里传的 选中的 整个的对象 "recipeEL" 再想上一层组件传递

    Tips: recipe.module.ts code:
    export class Recipe {
    //注意这里的class 名字自己取,但是开头字母要大写 constructor(public name: string, public description: string, public imagePath: string) {}
    }

    在这个组件里放了 Recipe 对象列表
    recipes: Recipe[] = [
    new Recipe(
    "name 千锋Web前端教程 1",
    "desc 千锋Web前端教程:35 添加内容到组件 千锋Web前端教程:35 添加内容到组件",
    "https://i.ytimg.com/vi/S4QsIz9eLdo/hqdefault.jpg?sqp=-oaymwEYCKgBEF5IVfKriqkDCwgBFQAAiEIYAXAB&rs=AOn4CLADbJI8vPDsx9RUrKlyd27mp46mYw"
    ),
    new Recipe(
    "2",
    "1",
    "https://ss0.baidu.com/73F1bjeh1BF3odCf/it/u=89521230,2695907708&fm=85"
    )]

  • recipes 主组件
    <app-recipe-list (recipesWasSelected)="selectedRecipe = $event"></app-recipe-list>
    <app-recipe-detail *ngIf="selectedRecipe; else defaultInfo" [recipe]="selectedRecipe">
    </app-recipe-detail>
    <ng-template #defaultInfo>请选择一个食谱 <br>如果变量 selectedRecipe 不存在值, 这里的内容就会显示
    </ng-template>

    import { Recipe } from "./recipe.module";
    selectedRecipe:Recipe;

    上面的其实是代替了 创建一个方法特意传参的冗余
    (recipesWasSelected)="selectThisOne($event)"
    selectThisOne(item:Recipe){
    this.selectedRecipe = item;
    }

  • Detail 详情组件
    <p>{{item.description}}</p>
    <img [src]="item.imagePath" alt="">

    import { Recipe } from "../recipe.module";
    @Input('recipe') item: Recipe;

子组件 add item 到父组件

  • 子组件 上有两个文本框,输入提交后给父组件传值
    <input id="name" #nameInput class="form-control" type="text">
    <input id="amount" #amountInput class="form-control">
    <button type="button" class="btn btn-success" (click)="onAddItem()">添加</button>

    import { ViewChild, ElementRef, Output, EventEmitter } from "@angular/core";
    import { Ingredient } from "../../../app/share/ingredient.module";

    @ViewChild("nameInput") myNameInput: ElementRef;
    @ViewChild("amountInput") myAmountInput: ElementRef;

    @Output() ingredientAdd: EventEmitter = new EventEmitter< {name: string,amount: string}>();

    onAddItem() {
    const newIngredient = new Ingredient(this.myNameInput.nativeElement.value,this.myAmountInput.nativeElement.value);
    this.ingredientAdd.emit(newIngredient);
    }
  • 父组件
    <app-shoping-edit (ingredientAdd) = "inIngredientAdd($event)"></app-shoping-edit>
    import { Ingredient } from "../../app/share/ingredient.module";
    ingredients: Ingredient[] = [ new Ingredient("土豆", 1) ];
    inIngredientAdd(ingredient: Ingredient) {
    this.ingredients.push(ingredient);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值