十七1991

十七1991 查看完整档案

沈阳编辑江南大学  |  高分子 编辑  |  填写所在公司/组织填写个人主网站
编辑

加油↖(^ω^)↗

个人动态

十七1991 回答了问题 · 2019-05-28

解决小程序chooseImage返回的图片数组不是按点选顺序

使用rxjs

forkJoin([uploadImage(xx1),uploadImage(xx2)..]).subscribe(results=>{
  console.log(results);
})

uploadImage也要改一下

uploadImage(){
 return Observable.create(observer=>{
   // 具体业务
   observer.next(成功返回结果);
   observer.complete();
 },err=>{observer.error()});
}

关注 2 回答 1

十七1991 评论了文章 · 2018-08-02

怎样设置babel-polyfill

Babel 包括一个垫片,这个垫片包含定制过的regenerator runtimecore-js

他会模拟es6环境,并且倾向在应用中使用而不是当作一个库或者工具。在使用babel-node时会自动加载。

这意味着你可以使用新的内置的东西如PromiseweakMap等。静态方法如Array.fromObject.assign等。实例方法Array.prototype.includegenerator函数(建议你使用regenator插件).polyfill会添加到全局的环境中,作为原生的原型如String那样的方式执行。

如果正在寻找那些不会定义到全局的库或者插件,查看transform-runtime插件。这样的话你就不能够使用上面提到的实例方法。如Array.prototype.includes

提示:
已使用ES2015的一些方法,不意味着你必须要使用babel-polyfill或者runtime plugin。你也许只是想要使用那些是需要用到的垫片(例如Object.assign),或者那些运行环境不存在需要加载的垫片。

安装

命令行

npm install --save babel-polyfill

在Node/Browserify/webpack中使用

要使用垫片你需要在应用开头的入口引入。
js

require("babel-polyfill")

如果你的英文入口使用ES6import语法,你应该在入口的开头替代导入垫片,以保证他是最先加载的:
js

import 'babel-polyfill'

webpack.config.js中加入babel-polyfill到你的入口数组:
js

module.exports = {
    entry:["babel-polyfill","./app/js"]
}

在浏览器中使用

在用npm下载的babel-polyfill文件中找到dist/polyfill.js文件。这个需要你在babel编译代码之前引入。你可以把它添加到你的编译文件最前面或者用<script>标签放到最前面。

查看原文

十七1991 提出了问题 · 2018-06-07

vue 在微信里指定页面跳转

先上图,图片能说的明白点
绿色是点击进入,黄色是微信左上角的返回
当我从A.html进入列表页,点击进入编辑信息以后,到成功页面,此时点击返回 要跳到历史记录里,再返回就回到列表页,再按返回就回到A.html
其实这个用beforeRouteLeave也是能做的,但是ios微信6.6.7出现一个前进按钮,我就不知道该怎么弄
有没有大神告诉我该怎么做

图片描述

关注 2 回答 0

十七1991 赞了文章 · 2018-05-31

Angular 4 ElementRef

Angular 的口号是 - "一套框架,多种平台。同时适用手机与桌面 (One framework.Mobile & desktop.)",即 Angular 是支持开发跨平台的应用,比如:Web 应用、移动 Web 应用、原生移动应用和原生桌面应用等。

为了能够支持跨平台,Angular 通过抽象层封装了不同平台的差异,统一了 API 接口。如定义了抽象类 Renderer 、抽象类 RootRenderer 等。此外还定义了以下引用类型:ElementRef、TemplateRef、ViewRef 、ComponentRef 和 ViewContainerRef 等。下面我们就来分析一下 ElementRef 类:

ElementRef的作用

在应用层直接操作 DOM,就会造成应用层与渲染层之间强耦合,导致我们的应用无法运行在不同环境,如 web worker 中,因为在 web worker 环境中,是不能直接操作 DOM。有兴趣的读者,可以阅读一下 Web Workers 中支持的类和方法 这篇文章。通过 ElementRef 我们就可以封装不同平台下视图层中的 native 元素 (在浏览器环境中,native 元素通常是指 DOM 元素),最后借助于 Angular 提供的强大的依赖注入特性,我们就可以轻松地访问到 native 元素。

ElementRef的定义

export class ElementRef {
  public nativeElement: any;
  constructor(nativeElement: any) { this.nativeElement = nativeElement; }
}

ElementRef的应用

我们先来介绍一下整体需求,我们想在页面成功渲染后,获取页面中的 div 元素,并改变该 div 元素的背景颜色。接下来我们来一步步,实现这个需求。

首先我们要先获取 div 元素,在文中 "ElementRef 的作用" 部分,我们已经提到可以利用 Angular 提供的强大的依赖注入特性,获取封装后的 native 元素。在浏览器中 native 元素就是 DOM 元素,我们只要先获取 my-app元素,然后利用 querySelector API 就能获取页面中 div 元素。具体代码如下:

import { Component, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <h1>Welcome to Angular World</h1>
    <div>Hello {{ name }}</div>
  `,
})
export class AppComponent {

  name: string = 'Semlinker';

  constructor(private elementRef: ElementRef) {
    let divEle = this.elementRef.nativeElement.querySelector('div');
    console.dir(divEle);
  }
}

运行上面代码,在控制台中没有出现异常,但是输出的结果却是 null 。什么情况 ? 没有抛出异常,我们可以推断 this.elementRef.nativeElement 这个对象是存在,但却找不到它的子元素,那应该是在调用构造函数的时候,my-app 元素下的子元素还未创建。那怎么解决这个问题呢 ?沉思中… ,不是有 setTimeout 么,我们在稍微改造一下:

constructor(private elementRef: ElementRef) {
  setTimeout(() => { // 此处需要使用箭头函数哈,你懂的...
      let divEle = this.elementRef.nativeElement.querySelector('div');
      console.dir(divEle);
   }, 0);
}

更新一下代码,此时控制台成功输出了 div 。为什么添加个 setTimeout 就能成功获取到想要的 div 元素呢?此处就不展开了,有兴趣的读者可以参考 - What the heck is the event loop anyway? 这个演讲的示例。

问题解决了,但感觉不是很优雅 ?有没有更好的方案,答案是肯定的。Angular 不是有提供组件生命周期的钩子,我们可以选择一个合适的时机,然后获取我们想要的 div 元素。

import { Component, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <h1>Welcome to Angular World</h1>
    <div>Hello {{ name }}</div>
  `,
})
export class AppComponent {

  name: string = 'Semlinker';

  // 在构造函数中 this.elementRef = elementRef 是可选的,编译时会自动赋值
  // function AppComponent(elementRef) { this.elementRef = elementRef; }
  constructor(private elementRef: ElementRef) { } 

  ngAfterViewInit() { // 模板中的元素已创建完成
    console.dir(this.elementRef.nativeElement.querySelector('div'));
    // let greetDiv: HTMLElement = this.elementRef.nativeElement.querySelector('div'); 
    // greetDiv.style.backgroundColor = 'red';
  }
}

运行一下上面的代码,我们看到了意料中的 div 元素。我们直接选用 ngAfterViewInit 这个钩子,不要问我为什么,因为它看得最顺眼咯。不过我们后面也会有专门的文章,详细分析一下 Angular 组件的生命周期。成功取到 div 元素,就剩下的事情就好办了,直接通过 style 对象设置元素的背景颜色。

功能虽然已经实现了,但还有优化的空间么?在 Angular 2 Decorators part - 2 文章中我们有谈到 Angular 内置的属性装饰器,如 @ContentChild、 @ContentChildren、@ViewChild、@ViewChildren 等。相信读者看完后,已经猜到我们的优化方案了。具体示例如下:

import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <h1>Welcome to Angular World</h1>
    <div #greet>Hello {{ name }}</div>
  `,
})
export class AppComponent {
  name: string = 'Semlinker';

  @ViewChild('greet')
  greetDiv: ElementRef;

  ngAfterViewInit() {
    this.greetDiv.nativeElement.style.backgroundColor = 'red';
  }
}

是不是感觉瞬间高大上了,不过先等等,上面的代码是不是还有进一步的优化空间呢 ?我们看到设置 div 元素的背景,我们是默认应用的运行环境在是浏览器中。前面已经介绍了,我们要尽量减少应用层与渲染层之间强耦合关系,从而让我们应用能够灵活地运行在不同环境。最后我们来看一下,最终优化后的代码:

import { Component, ElementRef, ViewChild, AfterViewInit, Renderer } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <h1>Welcome to Angular World</h1>
    <div #greet>Hello {{ name }}</div>
  `,
})
export class AppComponent {
  name: string = 'Semlinker';

  @ViewChild('greet')
  greetDiv: ElementRef;

  constructor(private elementRef: ElementRef, private renderer: Renderer) { }

  ngAfterViewInit() {
    // this.greetDiv.nativeElement.style.backgroundColor  = 'red';
    this.renderer.setElementStyle(this.greetDiv.nativeElement, 'backgroundColor', 'red');
  }
}

最后我们通过 renderer 对象提供的 API 优雅地设置了 div 元素的背景颜色。

我有话说

1.Renderer API 还有哪些常用的方法 ?

export abstract class Renderer {
  // 创建元素
  abstract createElement(parentElement: any, name: string, 
      debugInfo?: RenderDebugInfo): any;
  
  // 创建文本元素
  abstract createText(parentElement: any, value: string, 
      debugInfo?: RenderDebugInfo): any;
      
  // 设置文本
  abstract setText(renderNode: any, text: string): void;
      
  // 设置元素Property
  abstract setElementProperty(renderElement: any, propertyName: string, 
      propertyValue: any): void;
      
  // 设置元素Attribute
  abstract setElementAttribute(renderElement: any, attributeName: string, 
      attributeValue: string): void;    
      
  // 设置元素的Class
  abstract setElementClass(renderElement: any, className: string,
      isAdd: boolean): void;    
      
  // 设置元素的样式
  abstract setElementStyle(renderElement: any, styleName: string, 
      styleValue: string): void;    
}

需要注意的是在 Angular 4.x+ 版本,我们使用 Renderer2 替代 Renderer (Angular V2)。

2.Renderer2 API 还有哪些常用的方法 ?

export abstract class Renderer2 {
  abstract createElement(name: string, namespace?: string|null): any;
  abstract createComment(value: string): any;
  abstract createText(value: string): any;
  abstract setAttribute(el: any, name: string, value: string,
    namespace?: string|null): void;
  abstract removeAttribute(el: any, name: string, namespace?: string|null): void;
  abstract addClass(el: any, name: string): void;
  abstract removeClass(el: any, name: string): void;
  abstract setStyle(el: any, style: string, value: any, 
    flags?: RendererStyleFlags2): void;
  abstract removeStyle(el: any, style: string, flags?: RendererStyleFlags2): void;
  abstract setProperty(el: any, name: string, value: any): void;
  abstract setValue(node: any, value: string): void;
  abstract listen(
      target: 'window'|'document'|'body'|any, eventName: string,
      callback: (event: any) => boolean | void): () => void;
}

总结

本文主要介绍了 ElementRef 的作用和定义,然后通过一个简单的示例,展示了如何一步步优化已有的功能,希望对初学者能有所启发。

查看原文

赞 51 收藏 71 评论 26

十七1991 关注了用户 · 2018-05-18

阿宝哥 @angular4

http://www.semlinker.com/
聚焦全栈,专注分享 Angular、TypeScript、Node.js/Java 、Spring 技术栈等全栈干货

欢迎各位小伙伴关注本人公众号全栈修仙之路

关注 2274

十七1991 提出了问题 · 2018-05-17

解决angular4 动态创建组件

我想用Directive做一个公共的指令,当鼠标点击目标元素时,显示一个组件的内容,鼠标离开消失,
目前我是点击时用ViewContainerRef插入组件,
但是插入的组件与目标元素并列,而我想插入目标元素里面,
比如目标元素为<span appTxt><span/>,插入的组件的html为<span>hi<span/>
当我点击时,会变成<span appTxt><span/><span>hi<span/>
但wo 想要的效果是<span appTxt><span>hi<span/><span/>
@Directive({
selector: '[appTxt]',
})
export class TxtCopyDirective {

constructor(private el: ElementRef, private renderer2: Renderer2, public viewContainerRef: ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver) {

}

@HostListener('click', ['$event']) onclick(event: any) {

this.viewContainerRef.clear();
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(插入的组件);
this.viewContainerRef.createComponent(componentFactory);

}

}

关注 2 回答 1

十七1991 提出了问题 · 2017-11-07

ionic打包android报错

报错:cordovaProject.projectConfig.getFileResources is not a function
按照网上的办法npm install -g cordova@6
cordova platform add android@6
都试了,不好使,打包一下午了,求大神

关注 3 回答 2

十七1991 提出了问题 · 2017-10-26

ionic3 this.navctrl.pop()动画

我在做ios应用的时候发现一个问题,
当我点击左上角的返回,就是this.navCtrl.pop(), 这个过程的动画图片是最后消失的,而且很慢,
所以左上角那个返回的icon就会消失的很慢,怎么解决?

关注 3 回答 2

十七1991 赞了回答 · 2017-08-17

解决ionic 3怎样更改页面push的速度?

源码是这么写的

abstract push(page: Page | string, params?: any, opts?: NavOptions, done?: Function): Promise<any>;

其中NavOptions里面包含了

export interface NavOptions {
  animate?: boolean;
  animation?: string;
  direction?: string;
  duration?: number;
  easing?: string;
  id?: string;
  keyboardClose?: boolean;
  progressAnimation?: boolean;
  disableApp?: boolean;
  minClickBlockDuration?: number;
  ev?: any;
  updateUrl?: boolean;
  isNavRoot?: boolean;
}

你所要的速度就是direction
说了那么多,你要写的代码就是

constructor(public navCtrl: NavController) {}

push() {
    this.navCtrl.push(page, null, {
        direction: 0 // 毫秒
    });
}

关注 2 回答 1

十七1991 提出了问题 · 2017-08-16

解决ionic 3怎样更改页面push的速度?

在官网看到NavController的这几个方法,但是不知道怎么用
animatebooleanWhether or not the transition should animate.
animationstringWhat kind of animation should be used.
directionstringThe conceptual direction the user is navigating. For example, is the user navigating forward, or back?
durationnumberThe length in milliseconds the animation should take.
easingstringThe easing for the animation.

关注 2 回答 1

认证与成就

  • 获得 6 次点赞
  • 获得 93 枚徽章 获得 1 枚金徽章, 获得 28 枚银徽章, 获得 64 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2015-10-18
个人主页被 784 人浏览