当前位置: 首页 > news >正文

做网站镜像步骤百度搜索风云榜小说

做网站镜像步骤,百度搜索风云榜小说,wordpress媒体库增加分类,修改wordpress首页header第一个 Angular 项目 - 添加服务 这里主要用到的内容就是 [Angular 基础] - service 服务 提到的 前置项目在 第一个 Angular 项目 - 动态页面 这里查看 想要实现的功能是简化 shopping-list 和 recipe 之间的跨组件交流 回顾一下项目的结构: ❯ tree src/app/…

第一个 Angular 项目 - 添加服务

这里主要用到的内容就是 [Angular 基础] - service 服务 提到的

前置项目在 第一个 Angular 项目 - 动态页面 这里查看

想要实现的功能是简化 shopping-listrecipe 之间的跨组件交流

回顾一下项目的结构:

❯ tree src/app/
src/app/
├── directives
├── header
├── recipes
│   ├── recipe-detail
│   ├── recipe-list
│   │   ├── recipe-item
│   ├── recipe.model.ts
├── shared
│   └── ingredient.model.ts
└── shopping-list├── shopping-edit11 directories, 31 files

层级结构相对来说还是有一点点复杂的,所以如果在 app 层构建一个对应的变量和事件再一层层往下传,无疑是一件非常麻烦的事情(尤其 V 层和 VM 层都要进行事件传输的对应变化),而使用 service 就能相对而言比较简单的解决这个问题

创建新的 service

这里主要会创建两个 services:

src/app/
├── services
│   ├── ingredient.service.ts
│   └── recipe.service.ts

一个用来管理所有的 ingredients——这部分是放在 shopping-list 中进行展示的,另一个就是管理所有的 recipes

ingredient service

实现代码如下:

@Injectable({providedIn: 'root',
})
export class IngredientService {ingredientChanged = new EventEmitter<Ingredient[]>();private ingredientList: Ingredient[] = [new Ingredient('Apples', 5),new Ingredient('Tomatoes', 10),];constructor() {}get ingredients() {return this.ingredientList.slice();}addIngredient(Ingredient: Ingredient) {this.ingredientList.push(Ingredient);this.ingredientChanged.emit(this.ingredients);}addIngredients(ingredients: Ingredient[]) {this.ingredientList.push(...ingredients);this.ingredientChanged.emit(this.ingredients);}
}

代码分析如下:

  • Injectable

    这里使用 providedIn: 'root' 是因为我想让所有的组件共享一个 service,这样可以满足当 ingredient 页面修改对应的食材,并且将其发送到 shopping-list 的时候,数据可以进行同步渲染

  • ingredientChanged

    这是一个 event emitter,主要的目的就是让其他的组件可以 subscribe 到事件的变更

    subscribe 是之前的 service 笔记中没提到的内容,这里暂时不会细舅,不过会放一下用法

  • get ingredients()

    一个语法糖,这里的 slice 会创造一个 shallow copy,防止意外对数组进行修改

    也可以用 lodash 的 cloneDeep,或者单独创建一个函数去进行深拷贝

  • add 函数

    向数组中添加元素,并向外发送数据变更的信号

recipe service

@Injectable()
export class RecipeService {private recipeList: Recipe[] = [new Recipe('Recipe 1', 'Description 1', 'http://picsum.photos/200/200', [new Ingredient('Bread', 5),new Ingredient('Ginger', 10),]),new Recipe('Recipe 2', 'Description 2', 'http://picsum.photos/200/200', [new Ingredient('Chicken', 10),new Ingredient('Bacon', 5),]),];private currRecipe: Recipe;recipeSelected = new EventEmitter<Recipe>();get recipes() {return this.recipeList.slice();}get selectedRecipe() {return this.currRecipe;}
}

这里主要讲一下 Injectable,因为 recipe service 的部分应该被限制在 recipe 这个组件下,所以这里不会采用 singleton 的方式实现

其余的实现基本和上面一样

修改 recipe

这里依旧是具体业务具体分析:

  • recipe

    这里需要获取 activeRecipe + ngIf 去渲染 recipe-detail 部分的内容,如:

    没有选中 recipe选中了 recipe
    在这里插入图片描述在这里插入图片描述
  • recipe-detail

    这里需要 activeRecipe 去渲染对应的数据,如上图

  • recipe-list

    这里需要 recipes 去完成循环,渲染对应的 recipe-item

  • recipe-item

    这里需要 activeRecipe 完成对 active 这个 class 的添加

recipe 组件的修改

  • V 层修改:

    <div class="row"><div class="col-md-5"><app-recipe-list></app-recipe-list></div><div class="col-md-7"><app-recipe-detail[activeRecipe]="activeRecipe"*ngIf="activeRecipe; else noActiveRecipe"></app-recipe-detail><ng-template #noActiveRecipe><p>Please select a recipe to view the detailed information</p></ng-template></div>
    </div>
    
  • VM 层修改

    @Component({selector: 'app-recipes',templateUrl: './recipes.component.html',providers: [RecipeService],
    })
    export class RecipesComponent implements OnInit, OnDestroy {activeRecipe: Recipe;constructor(private recipeService: RecipeService) {}ngOnInit() {this.recipeService.recipeSelected.subscribe((recipe: Recipe) => {this.activeRecipe = recipe;});}ngOnDestroy(): void {this.recipeService.recipeSelected.unsubscribe();}
    }
    

这里主要是对 V 层进行了一些修改,减少了一些数据绑定。大多数的用法这里都是之前在 service 的笔记中提到的,除了这个 subscribe 的使用

简单的说,在 subscribe 之后,每一次 event 触发后,在这个 subscription 里,它都可以获取 event 中传来的信息,并进行对应的更新操作

recipe-list 组件的修改

  • V 层修改如下

    <div class="row"><div class="col-xs-12"><button class="btn btn-success">New Recipe</button></div>
    </div>
    <hr />
    <div class="row"><div class="col-xs-12"><app-recipe-item*ngFor="let recipe of recipes"[recipe]="recipe"></app-recipe-item></div>
    </div>
    
  • VM 层修改如下

    @Component({selector: 'app-recipe-list',templateUrl: './recipe-list.component.html',styleUrl: './recipe-list.component.css',
    })
    export class RecipeListComponent implements OnInit {recipes: Recipe[];constructor(private recipeService: RecipeService) {}ngOnInit() {this.recipes = this.recipeService.recipes;}
    }
    

这里主要就是获取数据的方式变了,也不需要向下传递 @Input,向上触发 @Output

reccipe-item 组件的修改

  • V 层

    <ahref="#"class="list-group-item clearfix"(click)="onSelectedRecipe()"[ngClass]="{ active: isActiveRecipe }"
    ><div class="pull-left"><h4 class="list-group-item-heading">{{ recipe.name }}</h4><p class="list-group-item-text">{{ recipe.description }}</p></div><span class="pull-right"><img[src]="recipe.imagePath"[alt]="recipe.name"class="image-responsive"style="max-height: 50px"/></span>
    </a>
    

    这里做的另外一个修改就是把 a 标签移到了 list-item 去处理,这样语义化相对更好一些

  • VM 层

    @Component({selector: 'app-recipe-item',templateUrl: './recipe-item.component.html',styleUrl: './recipe-item.component.css',
    })
    export class RecipeItemComponent implements OnInit, OnDestroy {@Input() recipe: Recipe;isActiveRecipe = false;constructor(private recipeService: RecipeService) {}ngOnInit() {this.recipeService.recipeSelected.subscribe((recipe: Recipe) => {this.isActiveRecipe = recipe.isEqual(this.recipe);});}onSelectedRecipe() {this.recipeService.recipeSelected.emit(this.recipe);}ngOnDestroy(): void {this.recipeService.recipeSelected.unsubscribe();}
    }
    

    这里变化稍微有一点多,主要也是针对 activeRecipeonSelectedRecipe 的修改。

    前者的判断我在 model 写了一个 isEqual 的方法用来判断名字、数量、图片等是否一样,当然只用这个方法的话还是有可能会出现数据碰撞的,因此写案例的时候我尽量不会用同一个名字去命名 ingredient。基于这个前提下,那么就可以判断当前的 recipe 是不是被选中的 recipe,同时添加 active 这一类名做更好的提示

    使用 subscribe 也是基于同样的理由,需要捕获 recipe 的变动

    onSelectedRecipe 的变化倒是没有太多,同样会触发一个事件,不过这个事件现在保存在 recipeService 中

    目前的实现是整个 recipe 都共享一个 service,因此这里 emit 的事件,在整个 recipe 组件下,只要 subscribe 了,就只会是同一个事件

recipe-detail 组件的修改

  • V 层

    <div class="row"><div class="col-xs-12"><imgsrc="{{ activeRecipe.imagePath }}"alt=" {{ activeRecipe.name }} "class="img-responsive"/></div>
    </div>
    <div class="row"><div class="col-xs-12"><h1>{{ activeRecipe.name }}</h1></div>
    </div>
    <div class="row"><div class="col-xs-12"><div class="btn-group" appDropdown><button type="button" class="btn btn-primary dropdown-toggle">Manage Recipe <span class="caret"></span></button><ul class="dropdown-menu"><li><a href="#" (click)="onAddToShoppingList()">To Shopping List</a></li><li><a href="#">Edit Recipe</a></li><li><a href="#">Delete Recipe</a></li></ul></div></div>
    </div>
    <div class="row"><div class="col-xs-12">{{ activeRecipe.description }}</div>
    </div>
    <div class="row"><div class="col-xs-12"><ul class="list-group"><liclass="list-group-item"*ngFor="let ingredient of activeRecipe.ingredients">{{ ingredient.name }} - {{ ingredient.amount }}</li></ul></div>
    </div>
    
  • VM 层

    @Component({selector: 'app-recipe-detail',templateUrl: './recipe-detail.component.html',styleUrl: './recipe-detail.component.css',
    })
    export class RecipeDetailComponent {@Input() activeRecipe: Recipe;constructor(private ingredientService: IngredientService) {}onAddToShoppingList() {this.ingredientService.addIngredients(this.activeRecipe.ingredients);}
    }
    

这里通过调用 ingredient service 将当前 recipe 中的 ingredient 送到 shopping-list 的 view 下,效果如下:

在这里插入图片描述

这里没有做 unique key 的检查,而且实现是通过 Array.push 去做的,因此只会无限增加,而不是更新已有的元素。不过大致可以看到这个跨组件的交流是怎么实现的

修改 shopping-list

这里的实现和 recipe 差不多,就只贴代码了

shopping-list 组件的修改

  • V 层

    <div class="row"><div class="col-xs-10"><app-shopping-edit></app-shopping-edit><hr /><ul class="list-group"><aclass="list-group-item"style="cursor: pointer"*ngFor="let ingredient of ingredients">{{ ingredient.name }} ({{ ingredient.amount }})</a></ul></div>
    </div>
    
  • VM 层

    @Component({selector: 'app-shopping-list',templateUrl: './shopping-list.component.html',styleUrl: './shopping-list.component.css',
    })
    export class ShoppingListComponent implements OnInit, OnDestroy {ingredients: Ingredient[] = [];constructor(private ingredientService: IngredientService) {}ngOnInit(): void {this.ingredients = this.ingredientService.ingredients;this.ingredientService.ingredientChanged.subscribe((ingredients: Ingredient[]) => {this.ingredients = ingredients;});}ngOnDestroy(): void {this.ingredientService.ingredientChanged.unsubscribe();}
    }
    

同样也是一个 subscription 的实现去动态监听 ingredients 的变化

shopping-edit 组件的修改

  • V 层

    <div class="row"><div class="col-xs-12"><form><div class="row"><div class="col-sm-5 form-group"><label for="name">Name</label><input type="text" id="name" class="form-control" #nameInput /></div><div class="col-sm-2 form-group"><label for="amount">Amount</label><inputtype="number"id="amount"class="form-control"#amountInput/></div></div><div class="row"><div class="col-xs-12"><div class="btn-toolbar"><buttonclass="btn btn-success mr-2"type="submit"(click)="onAddIngredient(nameInput)">Add</button><button class="btn btn-danger mr-2" type="button">Delete</button><button class="btn btn-primary" type="button">Edit</button></div></div></div></form></div>
    </div>
    

    这里添加了一个按钮的功能,实现添加 ingredient

  • VM 层

    @Component({selector: 'app-shopping-edit',templateUrl: './shopping-edit.component.html',styleUrl: './shopping-edit.component.css',
    })
    export class ShoppingEditComponent {@ViewChild('amountInput', { static: true })amountInput: ElementRef;constructor(private ingredientService: IngredientService) {}onAddIngredient(nameInput: HTMLInputElement) {this.ingredientService.addIngredient(new Ingredient(nameInput.value, this.amountInput.nativeElement.value));}
    }
    

    这里的 onAddIngredient 实现方式和添加整个 list 基本一致,也就不多赘述了

http://www.dinnco.com/news/32806.html

相关文章:

  • 好看的网站设计公司小网站搜什么关键词
  • 网站开发与设计开题报告电商数据查询平台
  • 网站建设公司专业网站开发需求百度文库首页
  • 怎么做班级网站如何建立网站服务器
  • 咨询聊城做网站网站优化查询
  • 互联网服务网站建设目的岳阳网站设计
  • 招聘网站建设的意义百度排名规则
  • 单页面 网站重庆网站外包
  • 淘宝客搜索网站怎么做潍坊seo建站
  • 聊城那里做网站建网站需要多少钱
  • 正规网站建设报价百度百度一下首页
  • 制作论文招聘网站的关键词点击排名系统
  • 网站开发z亿玛酷1专注企业培训内容有哪些
  • 福州婚庆网站建设哪个公司比较专业个人在线做网站免费
  • php网站怎么缓存谷歌推广怎么做最有效
  • 网站管理员容易做吗google搜索首页
  • 中国建行网站广州网站优化外包
  • 网站推广用什么方法最好全网线报 实时更新
  • 怎么做网站建设销售手机百度如何发布作品
  • 个人网站空间职业培训网络平台
  • gg模板网大型seo公司
  • 网站建设公司好做吗如何建立网站的步骤
  • 路桥做网站北京网站优化步
  • 做网站广告公司免费b2b网站推广有哪些
  • wordpress 简码使用淘宝seo是什么
  • 做3d办公家具教程的网站免费的推文制作网站
  • 完整个人网站htmlnba最新消息新闻
  • 做企业网站需要准备什么资料拼多多运营
  • 网站建设策划书的主要内容爱站网查询
  • 网站建设资源网站外包