Пользовательский элемент Aurelia пузырится / делегирует внутри функции? - PullRequest
0 голосов
/ 06 июня 2018

У меня есть пользовательский элемент, который отображает некоторый текст в промежутке, и если пользователь решает редактировать текст, я скрываю промежуток и отображаю ввод текста.Когда пользователь фокусируется на вводе текста, я скрываю ввод и снова отображаю интервал с обновленным текстом.Все это прекрасно работает.

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

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

Надеюсь, это имеет смысл!Заранее спасибо!

Вот несколько урезанных кодов.

custom-element.html:

<i if.bind="icon" class="${icon}"></i><span if.bind="!(allowEditTitle && isEditingTitle)" maxlength>${title}</span>
<input ref="titleInputEditor" type="text" value.bind="title" if.bind="allowEditTitle && isEditingTitle" maxlength="100" />

custom-element.ts

@bindable title: string;
@bindable allowEditTitle: boolean = false;
isEditingTitle: boolean = false;

toggleEditTitle() {
    let me = this;
    if (this.allowEditTitle === true) {
        this.isEditingTitle = !this.isEditingTitle;
    }
    if (this.isEditingTitle == true) {
        window.setTimeout(function () {
            $(me.titleInputEditor).focus();
            $(me.titleInputEditor).select();
            $(window).one('click', function () {
                if (me.isEditingTitle == true) {
                    me.toggleEditTitle();
                } 
            });
            $(me.titleInputEditor).one('click', function (e) {
                e.stopPropagation();
            });
            $(me.titleInputEditor).one('focusout', function () {
                me.toggleEditTitle();
            });
        });
    }
}

app.html

<custom-element title="Default Text" 
        allow-edit-title.bind="true" 
        on-???????.call="saveTextFunction">
</custom-element>

Ответы [ 3 ]

0 голосов
/ 06 июня 2018

Из того, что я вижу, вы пытаетесь связать функцию.Это делается с помощью привязки .call, это правильно.

Добавьте атрибут @bindable в свой пользовательский элемент и вызовите его с соответствующей позиции

@binable onUpdateChanges: Function;
updateText(){
   if(this.onUpdateChanges)
      this.onUpdateChanges();
}

в app.html, привязайте его следующим образом:

<custom-element title="Default Text" 
    allow-edit-title.bind="true" 
    on-update-changes.call="saveTextFunction()">
</custom-element>

в app.ts добавьте функцию saveTextFunction

saveTextFunction(){
      //Do stuff to update/save/persist something
}

, если вы хотите передать аргументы, вам нужно зарегистрировать onUpdateChanges в вашем пользовательском элементе немного по-другому

custom-element.ts

updateText(){
   if(this.onUpdateChanges)
      this.onUpdateChanges({text: what_ever_value_you_want_to_pass});
}

app.html

<custom-element title="Default Text" 
    allow-edit-title.bind="true" 
    on-update-changes.call="saveTextFunction(text)">
</custom-element>

app.ts

 saveTextFunction(text:string){
      //Do stuff to update/save/persist something
}
0 голосов
/ 07 июня 2018

Ответ Джесси (EventAggregator) - это путь, если вам нужно передать информацию между двумя элементами, расположенными на произвольных позициях в приложении (например, «всплытие» не всегда будет работать)

Schadensbegrenzer'sОтвет также будет работать в вашем конкретном случае, но я лично считаю, что передача функции через связываемый объект больше предназначена для динамической передачи поведения к пользовательским элементам, а не для связи между элементами.

Что бы я делал вваш случай фактически позволил событию вспыхнуть.Вы можете сделать это с помощью CustomEvent следующим образом:

custom-element.ts

$(me.titleInputEditor).one('focusout', function () {
    // it'd be slightly cleaner to inject `Element` in your CustomElement
    // and dispatch this event on that element instead
    me.titleInputEditor.dispatchEvent(new CustomEvent('input-changed', {
        detail: me, // if you want to pass this CustomElement instance up to the listener
        bubbles: true
    }));
    me.toggleEditTitle();
});

app.html

<custom-element title="Default Text" 
        allow-edit-title.bind="true" 
        input-changed.delegate="saveTextFunction">
</custom-element>
0 голосов
/ 06 июня 2018

Вы можете использовать aurelia-event-aggregator для этого.Вы можете опубликовать событие на вашем focusout и подписаться на это событие где-то еще в вашем коде (скорее всего, на сервисе), которое обновит вашу базу данных.


custom-element.ts

import { autoinject, EventAggregator } from "aurelia-framework";

@autoinject
export class CustomElement {
  constructor(private ea: EventAggregator)


...

        $(me.titleInputEditor).one('focusout', function () {
            me.ea.publish('input-changed', me.title);
            me.toggleEditTitle();
        });
...
}

service.ts

import { autoinject, EventAggregator } from "aurelia-framework";

@autoinject
export class Service {
  constructor(private ea: EventAggregator)

  public attached() {
    this.ea.subscribe('input-changed', (value) => {
       // update database using value
    });
  }
}

Для получения дополнительной документации по агрегатору событий см. здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...