【问题标题】:Dependency Injection Constructor that takes arguments接受参数的依赖注入构造函数
【发布时间】:2016-08-19 11:59:27
【问题描述】:

我正在构建一个 Aurelia 应用程序,它为每种类型的数据对象使用“模型”。

我所有的模型看起来都是这样的:

export class Item {
    id = null;
    name = '';
    description = '';

    constructor (data) {
        Object.assign(this, data);
    }
}

我后来创建了这样的对象:

export class SomeViewModel {
    activate () {
        this.myItem = new Item({
            name: 'My Item!', 
            description: 'This is my item. It will be initialized with these properties.'
        });
    }
}

我从阅读的一篇文章中获得了Object.assign() 位,它运行良好。它允许我使用来自服务器的数据创建新项目,或者如果我想要一个空项目,我根本不传递任何内容。

现在我已经到了需要我的模型能够访问另一个类的地步,所以我正在使用 Aurelia 的依赖注入,如下所示:

import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';

@inject(Router)
export class Item {
    id = null;
    name = '';
    description = '';

    constructor (router, data) {
        this.router = router;
        Object.assign(this, data);
    }

    get permalink () {
        return window.location.protocol + '//' + window.location.host + this.router.generate('item', {itemId: this.id});
    }
}

现在我的问题是这样的;如何创建new Item() 而不自己传递Router?我猜想将参数顺序切换到constructor() 可以解决问题,但这似乎不适用于 Aurelia?

而且我不想每次创建新项目时都这样做:

import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';

@inject(Router)
export class SomeViewModel {
    constructor (router) {
        this.router = router;
    }

    activate () {
        this.myItem = new Item(this.router, {
            name: 'My Item!', 
            description: 'This is my item. It will be initialized with these properties.'
        });
    }
}

肯定有更好的方法来解决这个问题?

【问题讨论】:

  • 只是一个想法:创建一个可以传递(注入)的项目工厂服务,您可以调用它来创建新项目。

标签: javascript mvvm dependency-injection aurelia


【解决方案1】:

使用Factory 解析器。这是一个例子:https://gist.run?id=46642ac54893186067e7cd890d6722a3**

import {inject, Factory} from 'aurelia-dependency-injection';
import {MyModel} from './my-model';

@inject(Factory.of(MyModel))
export class App {
  message = 'Hello World!';

  constructor(createModel) {
    let model = createModel('my data');
  }
}

my-model.js

import {inject} from 'aurelia-dependency-injection';
import {EventAggregator} from 'aurelia-event-aggregator';

@inject(EventAggregator)
export class MyModel {
  constructor(eventAggregator, data) {
    console.log(eventAggregator, data);
  }
}

【讨论】:

  • 好的,谢谢,你能解释一下这是如何工作的吗?我不是这需要 tbh 的额外代码的忠实粉丝,但如果这是这样做的方式,我想我别无选择..
  • 你会说为我的每个模型添加一个方法setData() 是一个更糟糕的解决方案吗?它至少可以让我继续使用几乎相同的代码,只有我会这样做this.myItem = new Item(); this.myItem.setData('my data')
  • 这种方法存在摩擦 - 您可能想退后一步,考虑不要将数据与模型类混合,而是构建对数据起作用而不成为数据的类。例如,如果您有 100 个数据项实例怎么办。你想实例化 100 个模型实例还是一个可以作用于 100 个数据项实例的事物的实例?
  • 好吧,我的想法至少是每个项目都应该是它自己的 Item 实例。但我可能做错了吗?我还为每个模型提供了一个服务来处理所有服务器通信。它通常类似于ItemService.getItemsBySomeParams(),然后ItemService 获取数据并在每个井中实例化一个Item 对象.. 项目
  • 注意到您之前已经回答过这个问题 :) stackoverflow.com/questions/34793723/…。真的希望有一种更顺畅的方式来实现这一目标。我不是Factory 解决方案的忠实拥护者,因为我需要更改我的代码很多。我也不太喜欢为每个模型添加 setData() 方法,因为这会阻止我对项目进行单列实例化...如果我只是忽略 DI 并在我的模型中创建一个 new Router() 怎么办.这是非常糟糕的做法吗?
猜你喜欢
  • 1970-01-01
  • 2011-02-02
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-17
  • 1970-01-01
相关资源
最近更新 更多