GVKun编程网logo

Parent child mysql

16

本文的目的是介绍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

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) 的使用

($children,$refs,$parent) 的使用

如果项目很大,组件很多,怎么样才能准确的、快速的寻找到我们想要的组件了??

  1. $refs
    首先你的给子组件做标记。demo :<firstchild ref="one"></firstchild>
    然后在父组件中,通过 this.$refs.one 就可以访问了这个自组件了,包括访问自组件的 data 里面的数据,调用它的函数
    注意
    ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
    当 v-for 用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组

  2. $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

如何解决.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 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

Angular 2 中的 ViewChildren 和 ContentChildren

原文地址:http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/

在这篇文章中,我将解释在Angular 2中view children和content children之间的区别,我们将看看如何从父组件来访问这两种不同的children,除了这些内容,我们也将提到在@Component 装饰器中提供的属性providersviewProviders之间的区别。

你可以在我的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>之间内容到模板内,select属性的值是一个CSS选择器,这使得我们可以选择我们想要投射的内容,例如在上面的例子中,footer将在所渲染的todo组件的底部被注入。

我们也可以不是用select属性,在这种情况下,我们将投射<todo-app></todo-app>之间的所有内容。

这里的实现很有很多组件,我们在这里并不不需要关心它们是怎么样实现,所以在这里忽略它们,应用的最终结果将是如下:

ViewChildren和ContentChildren

是的,它是那么的简单,现在,我们已经准备好来定义什么是view children和content children的概念。

  • 在组件的模板中定义的内容,它是组件的一部分,被称为view children
  • host元素<opening></closing>标签中的被称为content children

这意味着,在todo-app中的todo-inputtodo是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初始化时inputComponenttodoComponents不会被设置,它们的值要在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的相关知识,请在本站搜索。

本文标签: