2016-09-23 2 views
0

У меня есть html-файл, который использует настраиваемый компонент. Пользовательский компонент достигает и получает данные по методу bind(). Таким образом, когда компонент привязывается, он получает данные и соответственно устанавливает свойства. Этот компонент также имеет метод Save(), который при вызове должен отправить объект в базу данных.Доступ к данным пользовательских компонентов/методам

Теперь, в моем внешнем html-файле, я импортировал этот настраиваемый компонент. Поэтому у меня есть пользовательский компонент, а затем у меня есть кнопки отправки (а не часть пользовательского компонента), как это:

<custom-component></custom-component> 
<button click.trigger="submitCustomComponentData()"></button> 

Причина у меня нет кнопки в представлении пользовательского компонента, потому что это мнение не всегда будут иметь те же кнопки, что и делает компонент нерасширяемым.

Метод submitCustomComponentData() в основном вызывает метод обновления, который находится в моей виртуальной машине компонента.

Теперь, когда страница загружается, все работает идеально. Данные втягиваются, все мои входы предварительно заполнены предыдущими данными (из БД). Все прекрасно. Однако, когда я вызываю метод submitCustomComponentData() (или нажмите кнопку), я получаю сообщение об ошибке, потому что объект не заполняется. Это похоже на то, что я теряю экземпляр или что-то в этом роде.

Вот отрывок из некоторых важных частей:

Это то, что мой внешний HTML файл выглядит следующим образом. Он состоит из пользовательского компонента.

<template> 
    <require from="resources/components/dispatch-questions/dispatch-questions"></require> 

<section class="pages au-animate"> 
    <div class="row" id="dispatch-questions"> 
     <dispatch-questions></dispatch-questions> 
    </div> 
</section> 

</template> 

И VM для этого получает впрыскивается с компонентом диспетчерских-вопросы так:

constructor(private router: Router, private dq: DispatchQuestions) { 
    } 

Он также имеет метод click.trigger, который должен вызывать метод updateDB, который находится в компоненте. В этот момент компонент (который уже должен иметь тот же экземпляр, который был создан на bind()), должен передать этот объект в БД.

Но я получаю сообщение об ошибке, потому что по какой-то причине объект пуст. Функция в компоненте захватывает this.myObject и отправляет его в БД. Я думаю, что когда я вызываю функцию обновления из моей внешней виртуальной машины (а не из VM-компонента), я теряю экземпляр this компонента. Я думаю, что это проблема. Не уверен, как это исправить, если это проблема. Любая помощь была бы потрясающей!

Я попытался создать простую версию на Gist. https://gist.run/?id=f07b2eaae9bec27acda296189585ea6c

ответ

1

Для этого есть объяснение in the documentation.

Общее правило для Аурелии DI Использование

Всего этого синглтон прикладного уровня для тех вещей, которые классифицируются как «компонента», по существу пользовательских элементы, пользовательские атрибуты и просмотреть-модель, созданную с помощью исключения маршрутизатор или составной двигатель. Вы можете изменить время жизни роутера и состав созданных компонентов через явную конфигурацию.

Я бы рекомендовал использовать EventAggregator вместо инъекции. Такой подход обеспечивает гибкость, расширяемость и предотвращает также плотное соединение.

О выставке EventAggregator: #1 Walkthrough by Dwayne Charrington, Documentation, Contact Manager Tutorial.

Вот суть, чтобы продемонстрировать его с помощью сценария: https://gist.run/?id=f66eaa12e4183a72a7a3cc01ce3a8fb5

app.js

Давайте предположим, что мы хотели бы использовать более одного экземпляра Component пользовательского компонента. Для этого мы можем опубликовать событие component:save со связанными данными.

import { inject } from "aurelia-framework"; 
import { EventAggregator } from 'aurelia-event-aggregator'; 

@inject(EventAggregator) 
export class App { 

    components = [ 
    { id: 1, name: 'Component #' }, 
    { id: 2, name: 'Component #' }, 
    { id: 3, name: 'Component #' } 
    ]; 

    constructor(eventAggregator) { 
    this.eventAggregator = eventAggregator; 
    } 

    SubmitData(opts) { 
    this.eventAggregator.publish('component:save', opts); 
    } 

    // ... 
} 

component.js

Здесь можно подписаться на component:save событий и проверьте, должны ли мы продолжить с сохранением. По этой причине каждый экземпляр Component должен иметь уникальный идентификатор (номер, хэш, uid и т. Д.).

Примечание: есть важная часть очистки в detached, которая не упоминается в официальной документации. Вот почему я впервые опубликовал сообщение в блоге Дуэйн Чаррингтон.

import { inject, bindable } from 'aurelia-framework'; 
import { EventAggregator } from 'aurelia-event-aggregator'; 

@inject(EventAggregator) 
export class Component { 

    @bindable 
    id; 

    object = {}; 

    constructor(eventAggregator) { 
    this.eventAggregator = eventAggregator; 
    } 

    bind() { 
    this.object = { 
     "Name": `My name ${this.id}`, 
     "Age": 21 
    }; 

    console.log(`component ADDED: #${this.id}`); 

    this.subscriber = this.eventAggregator.subscribe('component:save', data => { 

     if (data.id === this.id || data.all === true) { 
     this.SubmitObjectToDatabase(); 
     console.log(`component:save SAVED: #${this.id}`, this.object.Name); 
     } else { 
     console.log(`component:save PASSED: #${this.id}`); 
     } 

    }); 
    } 

    SubmitObjectToDatabase() { 
    console.log(`SubmitObjectToDatabase has been called: #${this.id}`); 
    } 

    detached() { 
    // cleanup 
    this.subscriber.dispose(); 
    console.log(`component REMOVED: #${this.id}`); 
    } 
}