本文的目的是介绍Parentchildmysql的详细情况,我们将通过专业的研究、有关数据的分析等多种方式,同时也不会遗漏关于($children,$refs,$parent)的使用、.parent:
本文的目的是介绍Parent child mysql的详细情况,我们将通过专业的研究、有关数据的分析等多种方式,同时也不会遗漏关于($children,$refs,$parent) 的使用、.parent:hover仅适用于.children而不适用于.parent、Angular 2 ContentChild & ContentChildren、Angular 2 中的 ViewChildren 和 ContentChildren的知识。
本文目录一览:- Parent child mysql
- ($children,$refs,$parent) 的使用
- .parent:hover仅适用于.children而不适用于.parent
- Angular 2 ContentChild & ContentChildren
- Angular 2 中的 ViewChildren 和 ContentChildren
Parent child mysql
说我有一张这样的表:
=================================| ID | Parent_ID | Page_Name |=================================| 1 | NULL | Home || 2 | NULL | Services || 3 | 2 | Baking || 4 | 3 | Cakes || 5 | 3 | Bread || 6 | 5 | Flat Bread |---------------------------------
如何才能以这种格式对结果进行实际排序?即由父级->子级->子子级命令,根据我只要求说最多5个级别?我已经研究了“嵌套集模型”,但是对于我的要求而言,它似乎太复杂了。我不确定的是真正理解了可用于显示如上所示结果的SQL查询,或者在这种情况下,我应该使用像PHP这样的服务器端语言来帮我吗?
答案1
小编典典您可以尝试以下方法:
select t.*, (case when t4.parent_id is not NULL then 5 when t4.id is not null then 4 when t3.id is not null then 3 when t2.id is not null then 2 when t1.id is not null then 1 else 0 end) as levelfrom t left outer join t t1 on t.parent_id = t1.id left outer join t t2 on t1.parent_id = t2.id left outer join t t3 on t2.parent_id = t3.id left outer join t t4 on t3.parent_id = t4.idorder by coalesce(t4.parent_id, t4.id, t3.id, t2.id, t1.id, t.id), coalesce(t4.id, t3.id, t2.id, t1.id, t.id), coalesce(t3.id, t2.id, t1.id, t.id), coalesce(t1.id, t.id), t.id
如果层次结构是有限的,则不需要递归查询。
order by子句是棘手的部分。它只是从最高级别开始按层次结构的级别进行排序。
该版本的原始版本适用于问题中的数据。更广泛的测试发现它并不总是有效。我相信此版本始终有效。
($children,$refs,$parent) 的使用
如果项目很大,组件很多,怎么样才能准确的、快速的寻找到我们想要的组件了??
-
$refs
首先你的给子组件做标记。demo :<firstchild ref="one"></firstchild>
然后在父组件中,通过 this.$refs.one 就可以访问了这个自组件了,包括访问自组件的 data 里面的数据,调用它的函数
注意:
ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
当 v-for 用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组 -
$children
他返回的是一个组件集合,如果你能清楚的知道子组件的顺序,你也可以使用下标来操作;
3.$parent 在子组件中调用父组件的方法或获得其数据
parents.vue
<template>
<div id=''parents''>
<p>我是父组件
<button @click="click1hanlde">获取子组件1的数据与方法</button>
<button @click="click2hanlde">获取所有子组件的数据和方法</button></p>
<childCom1 ref="childCom1"></childCom1>
<childCom2 ref="childCom2"></childCom2>
</div>
</template>
<script>
import childCom1 from ''./childCom1.vue''
import childCom2 from ''./childCom2.vue''
export default {
components:{
childCom1, childCom2
},
data() {
return {
ParentData:''AAA''
};
},
methods:{
click1hanlde(){
console.log(this.$refs.childCom1.children_data);//children_data1
this.$refs.childCom1.children_fun();
},
click2hanlde(){
for(let i=0;i<this.$children.length;i++){
// console.log(this.$children.length);//2个组件 childCom1 childCom2
console.log(this.$children[i].children_data); //children_data2
this.$children[i].children_fun();
}
},
showParentData(){
console.log(this.ParentData)
}
}
};
</script>
childCom1.vue
<template>
<div id=''children1''>
<p>我是子组件1: <button @click="getParent_fun">获取父组件的数据和方法 </button></p>
</div>
</template>
<script>
export default {
data() {
return {
children_data:''children_data1'',
};
},
methods:{
children_fun(){
console.log(''我是子组件1的方法'')
},
getParent_fun(){
this.$parent.showParentData();
}
}
};
</script>
childCom2.vue
<template>
<div id=''children2''>
<p>我是子组件2</p>
</div>
</template>
<script>
export default {
data() {
return {
children_data:''children_data2'',
};
},
methods:{
children_fun(){
console.log(''我是子组件2的方法'')
}
}
};
</script>
.parent:hover仅适用于.children而不适用于.parent
如何解决.parent:hover仅适用于.children而不适用于.parent?
我在:hover上遇到麻烦。当我有以下代码时:
<div className="view-container"
<h2>abc</h2>
</div>
.view-container {
cursor: pointer;
Box-shadow: 0 6px 20px 0 rgba(0,0.15);
background-color: rgb(162,192,255);
}
.view-container :hover {
Box-shadow: 0 4px 8px 0 rgba(0,0.2),0 6px 20px 0 rgba(0,0.19);
}
h2 {
width: 100px;
}
悬停效果仅应用于h2部件,而不应用于我想要应用于其的div。我尝试在div和h2周围添加一个额外的div:
<div>
<div>
<h2>
然后将鼠标悬停在第二个div和h2上,这很奇怪,但是在那种情况下,我无法使它不适用于h2。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
Angular 2 ContentChild & ContentChildren
前面的文章我们已经介绍过了 Angular 2 的 ViewChild & ViewChildren 属性装饰器,现在我们就来介绍一下它们的兄弟 ContentChild 和 ContentChildren 属性装饰器。我想通过一个简单的需求,来引入我们今天的主题。具体需求如下:
熟悉 Angular 1.x 的用户,应该都知道 ng-transclude
指令,通过该指令我们可以非常容易实现上述的功能。而在 Angular 2 中引入新的 ng-content
指令,我们马上动手试一下。
greet.component.ts
import { Component } from ''@angular/core'';
@Component({
selector: ''exe-greet'',
template: `
<div>
<p>Greet Component</p>
<ng-content></ng-content>
</div>
`,
styles: [` .border { border: 2px solid #eee; } `]
})
export class GreetComponent { }
app.component.ts
import { Component } from ''@angular/core'';
@Component({
selector: ''my-app'',
template: `
<h4>Welcome to Angular World</h4>
<exe-greet>
<p>Hello Semlinker</p>
</exe-greet>
`,
})
export class AppComponent { }
以上代码运行后,浏览器的输出结果:
是不是感觉太简单了,那我们来升级一下需求,即我们的 GreetComponent 组件要支持用户自定义卡片风格的问候内容,具体如下图所示:
这个功能也很简单啊,我们马上看一下代码:
import { Component } from ''@angular/core'';
@Component({
selector: ''my-app'',
template: `
<h4>Welcome to Angular World</h4>
<exe-greet>
<div>
<div>Card Header</div>
<div>Card Body</div>
<div>Card Footer</div>
</div>
</exe-greet>
`,
})
export class AppComponent { }
以上代码运行后,浏览器的输出结果:
功能是实现了,但有没有什么问题 ?假设在另一个页面,也需要使用 GreetComponent 组件 ,那么还需要再次设置预设的样式。我们能不能把卡片风格的各个部分默认样式定义在 GreetComponent 组件中,使用组件时我们只需关心自定内容区域的样式,答案是可以的,调整后的代码如下:
import { Component } from ''@angular/core'';
@Component({
selector: ''exe-greet'',
template: `
<div>
<p>Greet Component</p>
<div>
<div>
<ng-content></ng-content>
</div>
<div>
<ng-content></ng-content>
</div>
<div>
<ng-content></ng-content>
</div>
</div>
</div>
`,
styles: [` .border { border: 2px solid #eee; } `]
})
export class GreetComponent{ }
GreetComponent 组件已经调整好了,现在剩下的问题就是如何从父级组件动态的抽取各个部分的内容。幸运的是,ng-content
指令支持 select
属性,它允许我们设定抽取的内容,更强大的是它支持我们常用的选择器类型,如标签选择器、类选择器、ID选择器、属性选择器等。
greet.component.ts - template
<div>
<div>
<ng-content select="header"></ng-content>
</div>
<div>
<ng-content select=".card_body"></ng-content>
</div>
<div>
<ng-content select="footer"></ng-content>
</div>
</div>
app.component.ts
import { Component } from ''@angular/core'';
@Component({
selector: ''my-app'',
template: `
<h4>Welcome to Angular World</h4>
<exe-greet>
<header>Card Header</header>
<div>Card Body</div>
<footer>Card Footer</footer>
</exe-greet>
`,
})
export class AppComponent { }
以上代码运行后,在浏览上我们可以看到预期的结果,接下来该我们的主角 - ContentChild 出场了。
ContentChild
在正式介绍 ContentChild 属性装饰器前,我们要先了解一下 Content Projection (内容投影)。
以前面的例子为例,我们在 AppComponent
组件中定义的内容,通过 ng-content
指令提供的选择器,成功投射到 GreetComponent 组件中。了解完 Content Projection,接下来我们来介绍 ContentChild。
ContentChild 是属性装饰器,用来从通过 Content Projection 方式设置的视图中获取匹配的元素。
@ContentChild 示例
child.component.ts
import { Component } from ''@angular/core'';
@Component({
selector: ''exe-child'',
template: `
<p>Child Component</p>
`
})
export class ChildComponent {
name: string = ''child-component'';
}
parent.component.ts
import { Component, ContentChild, AfterContentInit } from ''@angular/core'';
import { ChildComponent } from ''./child.component'';
@Component({
selector: ''exe-parent'',
template: `
<p>Parent Component</p>
<ng-content></ng-content>
`
})
export class ParentComponent implements AfterContentInit {
@ContentChild(ChildComponent)
childCmp: ChildComponent;
ngAfterContentInit() {
console.dir(this.childCmp);
}
}
app.component.ts
import { Component } from ''@angular/core'';
@Component({
selector: ''my-app'',
template: `
<h4>Welcome to Angular World</h4>
<exe-parent>
<exe-child></exe-child>
</exe-parent>
`,
})
export class AppComponent { }
以上代码运行后,控制台的输出结果:
ContentChildren
ContentChildren 属性装饰器用来从通过 Content Projection 方式设置的视图中获取匹配的多个元素,返回的结果是一个 QueryList 集合。
@ContentChildren 示例
parent.component.ts
import { Component, ContentChildren, QueryList, AfterContentInit } from ''@angular/core'';
import { ChildComponent } from ''./child.component'';
@Component({
selector: ''exe-parent'',
template: `
<p>Parent Component</p>
<ng-content></ng-content>
`
})
export class ParentComponent implements AfterContentInit {
@ContentChildren(ChildComponent)
childCmps: QueryList<ChildComponent>;
ngAfterContentInit() {
console.dir(this.childCmps);
}
}
app.component.ts
import { Component } from ''@angular/core'';
@Component({
selector: ''my-app'',
template: `
<h4>Welcome to Angular World</h4>
<exe-parent>
<exe-child></exe-child>
<exe-child></exe-child>
</exe-parent>
`,
})
export class AppComponent { }
以上代码运行后,控制台的输出结果:
ContentChild 接口及装饰器
ContentChildDecorator 接口
export interface ContentChildDecorator {
// Type类型:@ContentChild(ChildComponent)
(selector: Type<any>|Function|string, {read}?: {read?: any}): any;
new (selector: Type<any>|Function|string, {read}?: {read?: any}): ContentChild;
}
ContentChildDecorator 装饰器
export const ContentChild: ContentChildDecorator = makePropDecorator(
''ContentChild'',
[
[''selector'', undefined], {
first: true,
isViewQuery: false, // ViewChild或ViewChildren装饰器时为true
descendants: true,
read: undefined,
}
],
Query);
我有话说
ContentChildren 与 ViewChildren 的定义
在 host 元素
<opening>
和</closing>
标签中被称为 Content Children在组件的模板中定义的内容,它是组件的一部分,被称为 View Children
ContentChild 与 ViewChild 的异同点
相同点
都是属性装饰器
都有对应的复数形式装饰器:ContentChildren、ViewChildren
都支持 Type<any>|Function|string 类型的选择器
不同点
ContentChild 用来从通过 Content Projection 方式 (ng-content) 设置的视图中获取匹配的元素
ViewChild 用来从模板视图中获取匹配的元素
在父组件的 ngAfterContentInit 生命周期钩子中才能成功获取通过 ContentChild 查询的元素
在父组件的 ngAfterViewInit 生命周期钩子中才能成功获取通过 ViewChild 查询的元素
在 Root Component 中无法使用 `ng-content
原因主要有以下几点:
<my-app></my-app>
标签之间的信息是用来表明 Angular 的应用程序正在启动中Angular 2 编译器不会处理
index.html
文件中设置的绑定信息,另外出于安全因素考虑,为了避免index.html
中的{{}}
插值,被服务端使用的模板引擎处理。
总结
本文先通过一个简单的需求,引出了 Angular 2 中的 ng-content
指令,进而介绍了 Angular Content Projection (内容投影) 的概念,最后才正式介绍 ContentChild 和 ContentChildren 属性装饰器。另外在文末我们也介绍了 ContentChild 与 ViewChild 的异同点,希望本文能帮助读者更好地理解相关的知识点。
Angular 2 中的 ViewChildren 和 ContentChildren
原文地址:http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/
在这篇文章中,我将解释在Angular 2中view children和content children之间的区别,我们将看看如何从父组件来访问这两种不同的children,除了这些内容,我们也将提到在@Component
装饰器中提供的属性providers
和viewProviders
之间的区别。
你可以在我的github找到这篇文章的源代码,所以让我们开始吧!
组合基元(Composing primitives)
首先,让我们弄清Angular2组件(Component)和指令(Directive)概念之间的关系。组合模式是一个典型的设计模式用来开发用户界面。它使我们能够组成不同的基元,并以相同的方式对待它们。在函数式编程的世界中,我们可以组合函数。 例如:
map ((*2).(+1)) [1,2,3] -- [4,6,8]
上面是Haskell的代码,我们组合函数(*2)
和(+1)
,以便后面的列表中每个项目n被共同操作,操作顺序为n -> + 1 -> * 2
。
UI中的组成
那么,在用户界面,实际上相当类似的,我们可以将各个组件当做函数,这些函数可以被组合在一起,作为结果,我们得到更多复杂的功能。
在上图中,我们有2个元素
- Directive - 一个独立的持有一些逻辑的元素,但不包含任何结构。
- Component - 一个元素,它指定了Directive元素,并拥有其他指令实例的列表(这也可能是Component,因为Component继承Direcitve)。
这意味着,使用上述的抽象概念,我们可以构建以下形式的结构:
Angular 2中组件的组合
// ... @Component({ selector: 'todo-app',providers: [TodoList],directives: [TodoCmp,TodoInputCmp],template: ` <section> Add todo: <todo-input (onTodo)="addTodo($event)"></todo-input> </section> <section> <h4 *ngIf="todos.getAll().length">Todo list</h4> <todo *ngFor="var todo of todos.getAll()" [todo]="todo"> </todo> </section> <ng-content select="footer"></ng-content> ` }) class TodoAppCmp { constructor(private todos: TodoList) {} addTodo(todo) { this.todos.add(todo); } } // ...
是的,这将是“另一个MV* todo应用”。上面我们定义了一个组件selector是todo-app,它有一些内联模板,定义了一组指令,它或它的任何子组件可以使用。
我们可以以下列方式使用组件:
<todo-app></todo-app>
这基本上是一个XML,因为在<todo-app>
和</todo-app>
之间我们可以添加一些内容:
<todo-app> <footer> Yet another todo app! </footer> </todo-app>
ng-content
让我们先回到todo-app组件的定义,请注意模板的最后一行元素<ng-content select="footer"></ng-content>
,ng-content
会替换<todo-app>
和</todo-app>
之间内容到模板内,selec
t属性的值是一个CSS选择器,这使得我们可以选择我们想要投射的内容,例如在上面的例子中,footer
将在所渲染的todo组件的底部被注入。
我们也可以不是用select属性,在这种情况下,我们将投射<todo-app>
和</todo-app>
之间的所有内容。
这里的实现很有很多组件,我们在这里并不不需要关心它们是怎么样实现,所以在这里忽略它们,应用的最终结果将是如下:
ViewChildren和ContentChildren
是的,它是那么的简单,现在,我们已经准备好来定义什么是view children和content children的概念。
- 在组件的模板中定义的内容,它是组件的一部分,被称为view children
- 在
host
元素<opening>
和</closing>
标签中的被称为content children
这意味着,在todo-app
中的todo-input
和todo
是view children,而footer
(如果它被定义为Angular 2组件或指令)为content child。
访问 View 和 Content Children
现在到了有趣的部分!让我们看看我们如何能够访问和操作这两种类型的Children!
不同方式访问View Children
Angular 2 在 angular2/core
包中提供了下列属性装饰器:@ViewChildren
,@ViewChild
,@ContentChildren
和 @ContentChild
。
我们可以通过以下方式:
import {ViewChild,ViewChildren,Component...} from 'angular2/core'; // ... @Component({ selector: 'todo-app',template: `...` }) class TodoAppCmp { @ViewChild(TodoInputCmp) inputComponent: TodoInputCmp @ViewChildren(TodoCmp) todoComponents: QueryList<TodoCmp>; constructor(private todos: TodoList) {} ngAfterViewInit() { // available here } } // ...
上面例子显示我们如何使用@ViewChildren
和@ViewChild
,基本上,我们可以装饰一个属性,这样它会来查询视图中的某个元素,在上面例子中,使用@ViewChild
查询TodoInputCmp子组件和使用@ViewChildren
查询TodoCmp,我们使用不同的装饰器,是因为我们只有一个input
,所以我们用@ViewChild
来获取它,而我们有多个todo项,所以我们需要使用@ViewChildren
。
另外要注意的是的inputComponent和todoComponents的属性类型,第一个属性的类型是TodoInputCmp,如果Angular在组件控制器实例中还未发现该子组件或者引用,则它的值为空。另一方面,我们有多个TodoCmp实例,并可以从视图中动态的添加或移除,所以todoComponents属性的类型是QueryList<TodoCmp>
,我们可以认为QueryList
作为一个观察的集合,一旦项目被添加或删除它可以发出事件。
由于Angular的DOM编译todo-app
组件在它的子组件inputComponent实例化和todosComponent实例化之前,所以在todo-app
初始化时inputComponent
和todoComponents
不会被设置,它们的值要在ngAfterViewInit生命周期钩子被触发后才被设置。
访问Content Children
几乎是相同的规则来访问content children,但是,也有一些轻微的差别。为了更好地说明它们,让我们一起来看看它的使用:
@Component({ selector: 'footer',template: '<ng-content></ng-content>' }) class Footer {} @Component(...) class TodoAppCmp {...} @Component({ selector: 'app',styles: [ 'todo-app { margin-top: 20px; margin-left: 20px; }' ],template: ` <content> <todo-app> <footer> <small>Yet another todo app!</small> </footer> </todo-app> </content> `,directives: [TodoAppCmp,NgModel,Footer] }) export class AppCmp {}
在上面的代码段,我们定义了两个组件Footer和AppCmp,Footer可视化其host元素标签内的所有内容(<footer>content to be projected</footer>
)。
另一方面,AppCmp使用TodoAppCmp的标签来传递Footer,鉴于我们上面的术语,Footer是Content Child,我们可以以下列方式访问:
// ... @Component(...) class TodoAppCmp { @ContentChild(Footer) footer: Footer; ngAfterContentinit() { // this.footer is Now with value set } } // ...
我们从上面可以看到,View Children和Content Children的区别是装饰器的名字和生命周期不同,为了获取所有的Children,我们使用@ContentChildren
(如果只要获取一个,可以使用ContentChild),Children会在ngAfterContentinit
之后被设置
viewProviders vs providers
好吧!我们差不多讲完了,最后让我们来看下providers和viewProviders之间的区别,如果你还不熟悉Angular 2的依赖注入,可以看下该文章Angular 2中的依赖注入。
让我们来看下TodoAppCmp
class TodoList { private todos: Todo[] = []; add(todo: Todo) {} remove(todo: Todo) {} set(todo: Todo,index: number) {} get(index: number) {} getAll() {} } @Component({ // ... viewProviders: [TodoList],// ... }) class TodoAppCmp { constructor(private todos: TodoList) {} // ... }
在@Component
我们设置了viewProviders
属性,是一个数组,里面有一个元素TodoList
服务,TodoList
服务保存了所有todo项。
我们在TodoAppCmp构造函数中注入了TodoList服务,但我们也可以在TodoAppCmp视图中使用的其他指令(或组件)中注入该服务,这意味着下列组件可以使用TodoList:
- TodoList
- TodoCmp
- TodoInputCmp
但是,如果我们尝试在footer组件的构造函数中注入该服务,我们会得到以下运行时错误:
EXCEPTION: No provider for TodoList! (Footer -> TodoList)
这意味着在viewProviders
声明的只允许组件的模板内的组件使用。
如果我们想让Footer组件使用TodoList服务,可以将TodoList声明在providers属性中。
何时使用viewProviders
为什么要使用viewProviders?如果这些provider无法被content children访问到?假设你现在在开发第三方库,它内部使用一些服务,这些服务是库私有API的一部分,你不想让它们能被外部访问到,如果这些私有的内容注册在providers里用户可以通过content children来访问到这些私有的内容,但是如果你使用viewProviders,该providers将无法从外部访问
转自http://zai.io/topic/detail/news/fd4327d2fe6f801a
今天关于Parent child mysql的讲解已经结束,谢谢您的阅读,如果想了解更多关于($children,$refs,$parent) 的使用、.parent:hover仅适用于.children而不适用于.parent、Angular 2 ContentChild & ContentChildren、Angular 2 中的 ViewChildren 和 ContentChildren的相关知识,请在本站搜索。
本文标签: