首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >服务和常规打印类之间的接口?

服务和常规打印类之间的接口?
EN

Stack Overflow用户
提问于 2017-04-24 01:39:51
回答 2查看 3.1K关注 0票数 1

我有一个独特的情况,我发现自己被困住了。我有一个标准的类型记录类(.ts)扩展,它需要使用来自angular2服务的方法。到目前为止,我还没有办法做到这一点。

我将尽可能简单地解释这一点,因为我的代码库目前相当复杂。

所讨论的服务是operation.service.ts

代码语言:javascript
复制
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Operation } from './operation';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class OperationService {

  private operationCatalogue: Operation[] = [];
  private url = './src/app/operation-catalogue/operations.json';

  constructor(private http:Http) {
    this.init();
  }

  init(){
      this.fetchOperations().subscribe(res => {
        var i;
        for(i in res["operations"]){
          this.operationCatalogue[i] = new Operation(res["operations"][i]["name"],
                                                     res["operations"][i]["description"],
                                                     res["operations"][i]["iconName"],
                                                     res["operations"][i]["inputs"],
                                                     res["operations"][i]["outputs"]
                                                 );
        }
      });
  }

  getOperations(){
    return this.operationCatalogue;
  }

  fetchOperations(): Observable<Operation[]>{
      return this.http.get(this.url).map(res => res.json());
  }

  /*
  Get a single operation from the operation catalogue.
  */
  getOperation(name: String): Operation {
    var theOne;
    for (var i = 0; i < this.operationCatalogue.length; i++){
        if (this.operationCatalogue[i].name === name){
            theOne = this.operationCatalogue[i];
        }
    }
    return theOne;
  }
}

您将从这段代码中看到,服务从本地来源的Operation文件中找到的数据构建这些.json对象中的一个。在生产中,我的应用程序将从服务器而不是本地文件获取数据。

需要注意的重要方法是getOperation(),它接受一个字符串并从数组中返回一个Operation对象。

此服务是我的应用程序的关键部分,用于在另一个组件中填充HTML列表。

现在,我有另一个类,名为WSJSerializer。简单地说,为了给您提供一些上下文,这个类接受一个JSON字符串,它表示磁盘上找到的一个操作对象数组,并将它们转换为Operation对象。为了做到这一点,WSJSerializer getOperation() 需要使用 OperationService**.**的getOperation()方法。

WSJSerializer.ts

代码语言:javascript
复制
export class WSJDeserializer {

    private jsonString : string;
    private parsedString : Object;

    constructor(string : String){
        this.jsonString = <string> string;
        this.parsedString = JSON.parse(this.jsonString);
    }

    public deserialize() {
        var rootOp = this.parsedString["operation"];
        var childOps = rootOp["operations"];
        var numOps = childOps.length;

        for (var i = 0; i < numOps; i++){
            var childOp = childOps[i]["operation"];
            this.deserializeObject(childOp);
        }
    }

    private deserializeObject(operation : Object){
        //NEED TO USE THE getOperation() METHOD HERE!!!!
    }
}

这是我问题的症结所在。我无法与来自OperationServiceWSJSerializer接口,我猜这是某种角度限制。我尝试将import OperationService转换为WSJSerializer,然后调用getOperation()方法,但得到了以下错误:

代码语言:javascript
复制
WSJDeserializer.ts (25,26): Property 'getOperations' does not exist on type 'typeof OperationService'.)

如果不能直接调用getOperation() OperationService 的方法(不是OO概念接口)或助手类来解决问题,那么如何从 WSJSerializer**?** 中调用方法呢?还有其他解决办法吗?

其他资料:

  • WSJSerializer在我的应用程序的根角组件中使用,但OperationService不是。
  • OperationService在根组件的子组件中使用,根组件可以通过ViewChild()直接访问根组件。
  • WSJSerializer不是一个服务,因为它需要通过调用其他角度组件的方法来直接修改它们。

使用WSJSerializer的根组件:

代码语言:javascript
复制
import { WSJDeserializer } from './serialization/WSJDeserializer';

//services...
import { SerializationService } from './serialization/serialization.service';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
    providers: [SerializationService]
})
export class AppComponent implements OnInit {

    @ViewChild(PixiComponent) private pixiComponent : PixiComponent;
    @ViewChild(LogComponent) private logComponent : LogComponent;
    @ViewChild(EditGlobalNamesDialogBoxComponent) private globalNamesEditDialog : EditGlobalNamesDialogBoxComponent;
    @ViewChild(GlobalNamesComponent) private globalNamesComponent : GlobalNamesComponent;

    private globalNamesController : GlobalNamesController;

    ngOnInit() {
        this.globalNamesController = new GlobalNamesController(this.globalNamesEditDialog, this.globalNamesComponent, this.pixiComponent);
    }

    public leftMousedown(){
        this.pixiComponent.clickFromOutside();
    }

    public rightMousedown($event){
        $event.preventDefault();
        this.pixiComponent.clickFromOutside();
    }

    //TODO: Escape key functionality
    notifyEscapePressed(){

    }

    /*------------------------------------------------------------------------*/
    // Following method for log functionality

    public logData($event){
        this.logComponent.logText($event);
    }

    /*------------------------------------------------------------------------*/

    /*------------------------------------------------------------------------*/
    // Following methods for global names functionality 
    // handled by this.globalNamesController

    public globalNameEditRequest(data : EditGlobalNameRequestData){
        this.globalNamesController.displayEditGlobalNamesDialogBox(data);
    }

    public setNewGlobalName(data : EditGlobalNameRequestData) {
        this.globalNamesController.setNewGlobalName(data);
    }

    /*------------------------------------------------------------------------*/

    /*------------------------------------------------------------------------*/
    // Deserialization...

    public deserialize($event){
        var workspaceString : String = $event;
        var deserializer : WSJDeserializer = new WSJDeserializer(workspaceString)
        this.pixiComponent.resetCanvas();
        deserializer.deserialize();
    }

    /*------------------------------------------------------------------------*/
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-24 03:46:05

在当前状态下,WSJSerializer必须使用DI模式(而不是角度DI)来获取OperationService的实例。

代码语言:javascript
复制
export class WSJDeserializer {
    ...
    constructor(private operationService: OperationService, string : String){
        this.jsonString = <string> string;
        this.parsedString = JSON.parse(this.jsonString);
    }
    ...
    private deserializeObject(operation : Object){
        this.operationService.getOperation(...);
        ...
    }
}

它应该从实例化该类的可注入性传递,即组件:

代码语言:javascript
复制
new WSJDeserializer(workspaceString, this.operationService)

这看起来像是一个设计问题,正确的重构解决方案可能取决于问题中没有解释的其他因素。

一种可能是错误的东西被视为类的实体。是否真的需要一个包含状态(parsedString)并能够多次反序列化它的对象?如果没有序列化程序,则序列化程序可以成为接受字符串作为其方法参数的单例注入程序:

代码语言:javascript
复制
@Injectable()
export class WSJDeserializer {
    constructor(private operationService: OperationService) {}

    deserialize(string : String) {
            ...
            this.deserializeObject(string , childOp);
            ...
    }

    private deserializeObject(string : String, operation : Object){
        this.operationService.getOperation(...);
        ...
    }
}

另一种可能是,实体是正确的,但是确实需要有一个包含状态的实例,所以一个类是不够的。为了得到OperationService,单例注入应该以任何方式存在。因此,应该有两个类而不是一个类:

代码语言:javascript
复制
export class WSJDeserializable {
    ...
    constructor(string : String){
        this.jsonString = <string> string;
        this.parsedString = JSON.parse(this.jsonString);
    }
}

@Injectable()
export class WSJDeserializer {
    constructor(private operationService: OperationService) {}

    deserialize(deserializableObj: WSJDeserializable) {
            ...
            this.deserializeObject(deserializableObj, childOp);
            ...
    }
    ...
}

它应该从组件中传递:

代码语言:javascript
复制
const deserializableObj = new WSJDeserializable(...);
deserializer.deserialize(deserializableObj);

有更多的选项可以这样做,例如WSJDeserializer实例可以有创建WSJDeserializable实例的工厂方法,但是最终它仍然是一个单例,因为角服务是单个的(在单个注入器中)。

票数 2
EN

Stack Overflow用户

发布于 2017-04-24 02:54:59

那么,您需要OperationServiceWSJSerializer中的一个实例吗?只有一种方法可以做到这一点,那就是通过注射器。为了使WSJSerializer可注入,必须将其转换为服务。

嗯,这是个小谎言。还有另一种方法。如果不能使WSJSerializer成为服务,那么还需要确保OperationService也不是服务。这很容易做到。您可以使用本机库而不是使用Http服务( XmlHttpRequestfetch )(注意,只在现代浏览器上进行抓取)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43578519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档