不能注入提供者

时间:2017-09-12 22:11:53

标签: javascript angularjs angular-ui-router

Angular 1.6

我开发了dashboard application。已注册的信息中心组件有两种静态定义的#include <math.h> #include <stdio.h> #include <float.h> #include <stddef.h> #include <stdint.h> #include <string.h> #include <stdbool.h> #include <sndfile.h> // fabs wasn't accurate enough long double ldabs(long double x){ return x < 0 ? -x : x; } // -Inf<input<+Inf, -1<=output<=+1 long double infiniteToFinite( long double sample ){ // if the input value was too big, we'll just map it to -1 or 1 if( isinf(sample) ) return sample < 0 ? -1. : 1.; long double ret = sample / ( ldabs(sample) + 1 ); // Just in case of calculation errors if( isnan(ret) ) ret = sample < 0 ? -1. : 1.; if( ret < -1. ) ret = -1.; if( ret > 1. ) ret = 1.; return ret; } // -1<=input<=+1, -Inf<output<+Inf long double finiteToInfinite( long double sample ){ // if out of range, clamp to 1 or -1 if( sample > 1. ) sample = 1.; if( sample < -1. ) sample = -1.; long double res = -( sample / ( ldabs(sample) - 1. ) ); // sample was too close to 1 or -1, return largest long double if( isinf(res) ) return sample < 0 ? -LDBL_MAX : LDBL_MAX; return res; } // -1<input<1, -1<=output<=1 | Try to avoid input values too close to 1 or -1 long double addSamples( size_t count, long double sample[] ){ long double sum = 0; while( count-- ){ sum += finiteToInfinite( sample[count] ); if( isinf(sum) ) sum = sum < 0 ? -LDBL_MAX : LDBL_MAX; } return infiniteToFinite( sum ); } #define BUFFER_LEN 256 int main( int argc, char* argv[] ){ if( argc < 3 ){ fprintf(stderr,"Usage: %s output.wav input1.wav [input2.wav...]\n",*argv); return 1; } { SNDFILE *outfile, *infiles[argc-2]; SF_INFO sfinfo; SF_INFO sfinfo_tmp; memset( &sfinfo, 0, sizeof(sfinfo) ); for( int i=0; i<argc-2; i++ ){ memset( &sfinfo_tmp, 0, sizeof(sfinfo_tmp) ); if(!( infiles[i] = sf_open( argv[i+2], SFM_READ, &sfinfo_tmp ) )){ fprintf(stderr,"Could not open file: %s\n",argv[i+2]); puts(sf_strerror(0)); goto cleanup; } printf("Sample rate %d, channel count %d\n",sfinfo_tmp.samplerate,sfinfo_tmp.channels); if( i ){ if( sfinfo_tmp.samplerate != sfinfo.samplerate || sfinfo_tmp.channels != sfinfo.channels ){ fprintf(stderr,"Mismatching sample rate or channel count\n"); goto cleanup; } }else{ sfinfo = sfinfo_tmp; } continue; cleanup: { while(i--) sf_close(infiles[i]); return 2; } } if(!( outfile = sf_open(argv[1], SFM_WRITE, &sfinfo) )){ fprintf(stderr,"Could not open file: %s\n",argv[1]); puts(sf_strerror(0)); for( int i=0; i<argc-2; i++ ) sf_close(infiles[i]); return 3; } double inbuffer[argc-2][BUFFER_LEN]; double outbuffer[BUFFER_LEN]; size_t max_read; do { max_read = 0; memset(outbuffer,0,BUFFER_LEN*sizeof(double)); for( int i=0; i<argc-2; i++ ){ memset( inbuffer[i], 0, BUFFER_LEN*sizeof(double) ); size_t read_count = sf_read_double( infiles[i], inbuffer[i], BUFFER_LEN ); if( read_count > max_read ) max_read = read_count; } long double insamples[argc-2]; for( size_t j=0; j<max_read; j++ ){ for( int i=0; i<argc-2; i++ ) insamples[i] = inbuffer[i][j]; outbuffer[j] = addSamples( argc-2, insamples ); } sf_write_double( outfile, outbuffer, max_read ); } while( max_read ); sf_close(outfile); for( int i=0; i<argc-2; i++ ) sf_close(infiles[i]); } return 0; } 状态:ui.routerhome-dashboard

现在我想根据仪表板数据动态定义other-dashboard个状态。为此,我在ui.router内进行循环。但是为了获取仪表板数据,应将app.config提供程序注入配置中。

收到的错误是:

StorageService

如何注射提供者?有没有更好的方法来实现我的目标?

另外,我尝试将Error: [$injector:unpr] Unknown provider: StorageService 移动到父控制器$stateProvider。将其附加到dashboardController内的应用,例如app.config,然后将应用app.stateProvider = $stateProvider;导出到return default app;文件的末尾。

我得到的错误是app.js

提供商'return' outside of function它是一个模拟API的类,将来会从数据库中获取数据):

services/storage.service.js

app.js

class Storage {

  constructor () {
      this.dashboards = {
        'home': {
            id: '1',
            name: 'Home',
        view: 'home',
        url: '/home',
        component: 'homeDashboard',
            widgets: [{
                col: 0,
                row: 0,
                sizeY: 1,
                sizeX: 1,
                name: "Widget 1"
            }, {
                col: 2,
                row: 1,
                sizeY: 1,
                sizeX: 1,
                name: "Widget 2"
            }]
        },
        'other': {
            id: '2',
            name: 'Other',
        view: 'other',
        url: '/other',
        component: 'otherDashboard',
            widgets: [{
                col: 1,
                row: 1,
                sizeY: 1,
                sizeX: 2,
                name: "Other Widget 1"
            }, {
                col: 1,
                row: 3,
                sizeY: 1,
                sizeX: 1,
                name: "Other Widget 2"
            }]
        }
      };
  }

  saveDashboards(dashboards) {
    this.dashboards = dashboards;
  }

  listDashboards() {
    return this.dashboards;
  }

  $get() {
    return this.dashboards;
  }
}

export { Storage };

应用树:

import { DashboardCtrl } from './controllers/dashboardController';

import { homeDashboard } from './dashboards/home/homeDashboard.component';
import { otherDashboard } from './dashboards/other/otherDashboard.component';
import { aWidget } from './widgets/a_widget/aWidget.component';

import { Storage } from './services/storage.service.js';
import { Object2Array } from './filters/object2Array.js';

const app = angular.module('dashboardApp', [
    'ui.router',
    'ui.bootstrap',
    'gridster'
])
.controller('DashboardCtrl', DashboardCtrl)
.component('aWidget', aWidget)
.component('homeDashboard', homeDashboard)
.component('otherDashboard', otherDashboard)
//.factory('StorageService', () => new Storage())
.provider('StorageService', Storage)
.filter('object2Array', Object2Array);

app.config(function ($urlRouterProvider, $stateProvider, StorageService) {

  const dashboards = StorageService.listDashboards();

  _.forEach(dashboards, function (d) {
    $stateProvider.state({
      name: d.view,
      url: d.url,
      component: d.component
    });
  });

  /*
  const homeState = {
    name: 'home',
    url: '/home',
    component: 'homeDashboard'
  };

  const otherState = {
    name: 'other',
    url: '/other',
    component: 'otherDashboard'
  };

  $stateProvider.state(homeState);  
  $stateProvider.state(otherState); 
   */

  $urlRouterProvider.otherwise('/home');
});

UI看: enter image description here

2 个答案:

答案 0 :(得分:0)

StorageServiceprovider服务,在配置阶段可用作StorageServiceProvider服务提供商,在运行阶段可用作StorageService服务实例。

当注入StorageServiceProvider时,它将是Storage类的实例,当注入StorageService时,它将返回值$get方法({ {1}}对象)。

当服务实例依赖于其他服务时,需要

dashboardsproviderfactory服务。否则,可能会使用serviceconstant服务。

value类过分,因为它所做的就是为普通对象提供访问器方法。它可以是Storage服务,它将在配置和运行阶段以相同名称提供:

constant

答案 1 :(得分:0)

可以直接在控制器中定义路线。

首先,我们需要为控制器提供$stateProvider

...
app.config(function ($urlRouterProvider, $stateProvider) {
  app.stateProvider = $stateProvider;
  $urlRouterProvider.otherwise('/home');
});

export default app;

其次,我们在控制器内定义状态。

import app from '../app';
...
const DashboardCtrl = function ($scope, $timeout, StorageService) {
...
  forEach($scope.dashboards, function (dashboard) {
    app.stateProvider.state({
      name: dashboard.name,
      url: dashboard.url,
      component: dashboard.component
    });
  });
});