zoukankan      html  css  js  c++  java
  • angular11源码探索二[Renderer2]

    其实我通过这段时间的深入学习,已经写到第6,7篇的,每天晚上都熬夜很晚,我发现了angular的宝贵东西,也慢慢明白了这个好东西,由于第一篇个人写的质量比较高,后面写的质量不高,感觉有点初级,一直没发,自己也开始迷茫了,研究源码的目标是为了什么,啃源码是一个很迷茫很打击自信有挑战性的东西,需要要一堆迷迷糊糊的东西去理解本质,加上前面几个月没怎么深入angular导致很多东西也忘记了,自己也是抱着一个初学者的态度去探究源码,已经编写的质量一直达不到自己的要求,但是我编写的一些东西,都是抱着初学者的态度去理解的,对于解决问题和从实际问题去理解angular还是有很大帮助的

    技术成长分为三个阶段:

    第一阶段:化难为易

    第二阶段:由易变难

    第三阶段:分割难易

    自己的编写的时候是不是应该先做个第一阶段的事,理解怎么能全面的去,精通这个api,官网上面的介绍,说实例有点浅,自己能不能做到,遇到这个api基本能理解全部的方法,相信自己能编写20篇过后的质量可能有明显的提高,所以急不来,慢慢来,别过于抱着目的性去弄,有时候遇到太难的问题,容易导致心态崩溃,可以跟以前一样,从源码的基础上去啃透这个api,希望未来的自己能变得更强,学东西还是尽量让自己变得更加自信...

    Renderer2

    <div data="[1,2,3]" #apps>121212</div>
    
    export class UserComponent implements OnInit ,AfterViewInit{
      @ViewChild('apps') ages:ElementRef;
    
      constructor(private kvDiffers: KeyValueDiffers, private http: HttpClient,private renderer:Renderer2) {}
    
    ngAfterViewInit() {
    // 创建dom
      let app = this.renderer.createElement('div');
     // 创建文本
      let text = this.renderer.createText('大帅比');
      // 创建注释
      let com=this.renderer.createComment('我是注释')
      
      //添加创建的dom
      this.renderer.appendChild(this.ages.nativeElement,app)
      //添加创建的文字
      this.renderer.appendChild(this.ages.nativeElement,text)
      this.renderer.appendChild(this.ages.nativeElement,com)
    }
    }
    

    insertBefore

    this.renderer.insertBefore(父节点,要添加的子节点newChild,现节点前面添加newChild,isMove:boolean  是否触发动画)
    

    removeChild

    this.renderer.removeChild(父节点,删除的子节点,)
    

    删除所有子节点

    const childElements = this.el.nativeElement.children;
    for (let child of childElements) {
      this.renderer.removeChild(this.el.nativeElement, child);
    }
    

    源码地址

    packagesplatform-browsersrcdomdom_renderer.ts

    createElement

     export const NAMESPACE_URIS: {[ns: string]: string} = {
      'svg': 'http://www.w3.org/2000/svg',
      'xhtml': 'http://www.w3.org/1999/xhtml',
      'xlink': 'http://www.w3.org/1999/xlink',
      'xml': 'http://www.w3.org/XML/1998/namespace',
      'xmlns': 'http://www.w3.org/2000/xmlns/',
    };
    
    createElement(name: string, namespace?: string): any {
        if (namespace) {
          // 命名空间,个人觉得没多大用处
          return document.createElementNS(NAMESPACE_URIS[namespace] || namespace, name);
        }
        return document.createElement(name);
      }
    
    // 创建文本
      createText(value: string): any {
        return document.createTextNode(value);
      }
    // 添加dom   ,父节点        子节点
      appendChild(parent: any, newChild: any): void {
        parent.appendChild(newChild);
      }
    // 插入节点,    父节点      新的子节点        现有的前面插入(新的子节点)
      insertBefore(parent: any, newChild: any, refChild: any): void {
        if (parent) {
          parent.insertBefore(newChild, refChild);
        }
      }
    // 父节点直接删除子节点
      removeChild(parent: any, oldChild: any): void {
        if (parent) {
          parent.removeChild(oldChild);
        }
      }
    
    // 卧槽竟然原生里面可以创造出,注释
      createComment(value: string): any {
        return document.createComment(value);
      }
    

    剩下的几个属性

    //父节点  
    parentNode(node: any): any {
        return node.parentNode;
      }
    // 下一个兄弟节点
      nextSibling(node: any): any {
        return node.nextSibling;
      }
    // 设置
      setAttribute(el: any, name: string, value: string, namespace?: string): void {
          // 有命令空间
        if (namespace) {
         ...
        } else {
          el.setAttribute(name, value);
        }
      }
    // 删除属性
      removeAttribute(el: any, name: string, namespace?: string): void {
        // 有命令空间的删去
          if (namespace) {
      	... 
        } else {
          el.removeAttribute(name);
        }
      }
    // 添加class
      addClass(el: any, name: string): void {
        el.classList.add(name);
      }
    // 删除class
      removeClass(el: any, name: string): void {
        el.classList.remove(name);
      }
    
      export enum RendererStyleFlags2 {
      Important = 1 << 0,
          // 1
      DashCase = 1 << 1
          // 2
    }
    
    
    setStyle(el: any, style: string, value: any, flags: RendererStyleFlags2): void {
        if (flags & (RendererStyleFlags2.DashCase | RendererStyleFlags2.Important)) {
          el.style.setProperty(style, value, flags & RendererStyleFlags2.Important ? 'important' : '');
        } else {
          el.style[style] = value;
        }
      }
    
      removeStyle(el: any, style: string, flags: RendererStyleFlags2): void {
        if (flags & RendererStyleFlags2.DashCase) {
          el.style.removeProperty(style);
        } else {
          // IE 情况下 null为删除样式
          el.style[style] = '';
        }
      }
    

    第四个参数是可选参数,默认是添加优先级

        this.renderer.setStyle(a,'background','red',1) //添加优先级,2是取消优先级
    也可以使用枚举的形式
        this.renderer.setStyle(a,'background','red',RendererStyleFlags2.Important) 
    也可以直接在第三个参数上添加
     this.renderer.setStyle(a,'background','red!important')
    

    setProperty

    修改内置属性

    // 摇摆树的内容暂时不太懂
    const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
    
    setProperty(el: any, name: string, value: any): void {
        NG_DEV_MODE && checkNoSyntheticProp(name, 'property');
        el[name] = value;
      }
    
    const AT_CHARCODE = (() => '@'.charCodeAt(0))();
    const AT_CHARCODE =  '@'.charCodeAt(0);
    // 思考这两种写法有什么区别...
    function checkNoSyntheticProp(name: string, nameKind: string) {
      if (name.charCodeAt(0) === AT_CHARCODE) {
        throw new Error(`Found the synthetic ${nameKind} ${
            name}. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.`);
      }
    }
    

    属性name第一个参数不能是@

    this.renderer.setProperty(a,'type','button') // 修改input的type类型
    

    setValue

      setValue(node: any, value: string): void {
        node.nodeValue = value;
      }
    
      let a = document.querySelector('#bbb');
        a.childNodes[0].nodeValue='bbb'
    

    nodeValue 文本节点

    childNodes 子节点合集

    nodeName 节点名称 大写的 DIV或者其他标签

    nodeType 节点类型

    • 元素节点 1
    • 属性节点 2
    • 文本节点 3
    • 注释节点 8

    案例

      <div id="bbb">
      dddd
      </div>	
    要有文本节点才能添加
      let a = document.querySelector('#bbb');
      this.renderer.setValue( a.childNodes[0],'eeee')
    

    listen

    用法

    let a = document.querySelector('#bbb');
        this.renderer.listen(a,'click',e=>{
          console.log(e);
        })
    
  • 相关阅读:
    课程总结
    第十四周课程总结&实验报告
    第十三周课程总结
    第十二周课程总结
    第十一周课程总结
    第十周课程总结
    第七次java实验报告
    第六次java实验报告
    第五次java实验报告
    第四次java实验报告
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14106397.html
Copyright © 2011-2022 走看看