Ember传递回调服务 - 未定义此

时间:2016-11-22 04:43:07

标签: ember.js ember-2.0.0

我有一个服务来上传许多大块文件

export default Ember.Service.extend({
  run(files, callbacks) {
    // ugly async FileReader and ajax
    // calling callbacks during the process
  }
})

我需要一堆回调来显示进度,但问题是this在这些回调中未定义

export default Ember.Component.extend({
  upload: Ember.inject.service(),

  didInsertElement() {
    // bind fileinput change event to set up pending files
  },

  ondonesingle(self, file, uuid) {
    // this is undefined
    // self is real this
  },

  actions: {
    submit() {
      let callbacks = {
        ondoneall: this.ondoneall,
        ondonesingle: this.ondonesingle,
        onprogressall: this.onprogressall,
        onprogresssingle: this.onprogresssingle,
        onerror: this.onerror,
        object: this // will be passed as first argument to each callback
      };
      this.get('upload').run(this.get('pending_files'), callbacks);
    },
  }
})

要解决这个问题,我必须随处参考。

它有效,但感觉非常错误。在恩伯最好的做法是什么?可观察的属性也感觉不对,我如何观察2000个文件的进度?将所有内容放在一个大对象中并在整个应用程序中共享它?

1 个答案:

答案 0 :(得分:2)

Shader "Custom/Blur" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _BumpAmt ("Distortion", Range (0,128)) = 10 _MainTex ("Tint Color (RGB)", 2D) = "white" {} _BumpMap ("Normalmap", 2D) = "bump" {} _HorizontalDistort ("Horizontal Distortion", Float) = 1.0 _VerticalDistort ("Vertical Distortion", Float) = 1.0 } Category { // We must be transparent, so other objects are drawn before this one. Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Opaque" } SubShader { // Horizontal blur GrabPass { Tags { "LightMode" = "Always" } } Pass { Tags { "LightMode" = "Always" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" struct v2f { float4 vertex : POSITION; float4 uvgrab : TEXCOORD0; }; v2f vert (v2f v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); #if UNITY_UV_STARTS_AT_TOP // Only true in directX platforms float scale = -1.0; #else float scale = 1.0; #endif o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5; o.uvgrab.zw = o.vertex.zw; return o; } sampler2D _GrabTexture; float4 _GrabTexture_TexelSize; float _HorizontalDistort; half4 frag( v2f i ) : COLOR { half4 sum = half4(0,0,0,0); #define GRABPIXEL(kernelx) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx*_HorizontalDistort, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) sum += GRABPIXEL(-4.0) * 0.05; sum += GRABPIXEL(-3.0) * 0.09; sum += GRABPIXEL(-2.0) * 0.12; sum += GRABPIXEL(-1.0) * 0.15; sum += GRABPIXEL(0.0) * 0.18; sum += GRABPIXEL(+1.0) * 0.15; sum += GRABPIXEL(+2.0) * 0.12; sum += GRABPIXEL(+3.0) * 0.09; sum += GRABPIXEL(+4.0) * 0.05; return sum; } ENDCG } // Vertical blur GrabPass { Tags { "LightMode" = "Always" } } Pass { Tags { "LightMode" = "Always" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" struct v2f { float4 vertex : POSITION; float4 uvgrab : TEXCOORD0; }; v2f vert (v2f v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); #if UNITY_UV_STARTS_AT_TOP float scale = -1.0; #else float scale = 1.0; #endif o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5; o.uvgrab.zw = o.vertex.zw; return o; } sampler2D _GrabTexture; float4 _GrabTexture_TexelSize; float _VerticalDistort; half4 frag( v2f i ) : COLOR { half4 sum = half4(0,0,0,0); #define GRABPIXEL(kernely) tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely*_VerticalDistort, i.uvgrab.z, i.uvgrab.w))) sum += GRABPIXEL(-4.0) * 0.05; sum += GRABPIXEL(-3.0) * 0.09; sum += GRABPIXEL(-2.0) * 0.12; sum += GRABPIXEL(-1.0) * 0.15; sum += GRABPIXEL(0.0) * 0.18; sum += GRABPIXEL(+1.0) * 0.15; sum += GRABPIXEL(+2.0) * 0.12; sum += GRABPIXEL(+3.0) * 0.09; sum += GRABPIXEL(+4.0) * 0.05; return sum; } ENDCG } } } } 回来this的原因是当函数传递时它的上下文(undefined)发生了变化。您可以创建一个新函数,使用this显式设置其上下文。使用function.bind时,无论您在何处调用新函数或将其赋值给的值/属性,它的上下文都将保持不变。

see MDN for Function.prototype.bind

function.bind