Привязка Aurelia к функции с параметром и принудительное обновление - PullRequest
1 голос
/ 28 октября 2019

Я связал функцию isSelected (item) с моей кнопкой, которая переключит класс, чтобы показать, выбран он или нет, однако эта функция не будет обновляться при изменениях.

Я не могу использовать вычисленнуюсвойство, поскольку оно принимает параметр.

Есть ли способ заставить эту работу работать с связанной функцией и заставить ее идеально обновляться с помощью декоратора @computedFrom или подобного?

Пример здесь:

https://codesandbox.io/s/aurelia-typescript-sandbox-8oksr?fontsize=14

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

-

причина для этого

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

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Обновление 2

Итак, я столкнулся с этой проблемой на github . В одном из ответов указывалось, что передача наблюдаемого объекта в метод автоматически делает метод наблюдаемым. В настоящее время вы только передаете person в isSelected(). Но человек не меняется. Я думаю, что вы можете выполнить то, что вы ищете, изменив свой метод isSelected() следующим образом (обратите внимание на изменение вызова isSelected в привязке класса кнопки):

vm.ts

public isSelected(person, length){
   return this.selections.find(item => item.name === person.name);
}

view.html

<button
    class="btn-gradient mini ${isSelected(person, selections.length) ? 'green': 'red'}"
    click.delegate="selectPerson(person)"
    repeat.for="person of people">
    ${person.name}
  </button>

Пример: https://codesandbox.io/s/aurelia-typescript-sandbox-oelt7?fontsize=14

Исходное сообщение

Я борюсь с той же проблемой, пытаясь реализовать метод isSelected() для управления выбранным классом индикатора. Я изучил @computedFrom.

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

@computedFrom('firstName', 'lastName')
get fullName() { return `${firstName} ${lastName}`}

Итак, проблема с тем, что мы хотим сделать, заключается в том, что нам нужно передать индекс или элемент в наш метод, что лишает нас возможности использовать @computedFrom.

Альтернативу, которую яне очень нравится ... но это работает , это значит добавить свойство isSelected к каждому из ваших личных объектов. Тогда ваш код будет выглядеть примерно так:

vm.ts

selectPerson(person){
    person.isSelected = !person.isSelected;  //De-selects if already selected
}

view.html

<button
class="btn-gradient mini ${person.isSelected ? 'green': 'red'}"
click.delegate="selectPerson(person)"
repeat.for="person of people">${person.name}</button>

(или, как мне недавно предложили, оберните ваш объект person в класс-оболочку)

public class SelectableWrapper {
   constructor(public person : Person, public isSelected : boolean){}
}

Обновление 1

Для решения проблемы отображенияСписок выбранных элементов (а также «раскраска» выбранных элементов) можно сделать следующим образом (в дополнение к тому, что я уже показал):

vm.ts

//Remove selections property and add it as a getter
get selections(){
   return this.people.filter(p => p.isSelected);
}

view.html

<div repeat.for = "person of selections">
   ${person.name}
</div>

Пример здесь: https://codesandbox.io/s/aurelia-typescript-sandbox-u92nk?fontsize=14

0 голосов
/ 28 октября 2019

множественный выбор с использованием сигнализатора

import "./app.css";
import {BindingSignaler} from 'aurelia-templating-resources';
import { inject } from "aurelia-framework";

@inject(BindingSignaler)
export class App {
  message = "Hello World!";
  message2 = "Hello World2!";
  people = [{ name: "Person 1" }, { name: "Person 2" }, { name: "Person 3" }];
  selections = [];

  constructor(private signaler: BindingSignaler) {
    this.selections.push(this.people[1]);
  }

  selectPerson(person) {
    this.selections.push(person);
    this.signaler.signal('select-signal')
  }

  color(person) {
    return this.selections.includes(person) ? 'green' : 'red';
  }
}
<template>
  <h1>People</h1>

  <div repeat.for="person of selections">
    ${person.name}
  </div>

  <button
    class="btn-gradient mini ${color(person) & signal:'select-signal' }"
    click.delegate="selectPerson(person)"
    repeat.for="person of people"
  >
    ${person.name}
  </button>
</template>

одиночный выбор

добавление selected в класс, назначениеperson в нем при изменении и затем использовать selected === person в качестве условия

import "./app.css";

export class App {
  message = "Hello World!";
  message2 = "Hello World2!";
  people = [{ name: "Person 1" }, { name: "Person 2" }, { name: "Person 3" }];
  selections = [];

  // add selected
  selected = null;

  constructor() {

    // use selectPerson
    this.selectPerson(this.people[1]);
  }

  selectPerson(person) {
    this.selections.push(person);

    // assign person to selected
    this.selected = person;
  }
}

<template>
  <h1>People</h1>

  <div repeat.for="person of selections">
    ${person.name}
  </div>

  <!-- use `selected === person` as condition -->
  <button
    class="btn-gradient mini ${selected === person ? 'green': 'red'}"
    click.delegate="selectPerson(person)"
    repeat.for="person of people"
  >
    ${person.name}
  </button>
</template>

...