recorrer objetos objeto lista convertir array javascript aurelia aurelia-binding

lista - recorrer array de objetos javascript



Observe la propiedad en una matriz de objetos para cualquier cambio (4)

Además de los ejemplos de Jeremy, puede crear un configurador personalizado, por ejemplo:

class Item { // this is your ~private~ field _isSelected = false; // in our constructor, we pass the view model and the property name constructor(vm, prop, name) { this.vm = vm; this.prop = prop; this.name = name; } get isSelected() { return this._isSelected; } // when you set the value, you increase the vm''s property set isSelected(value) { if (value !== this._isSelected) { this.vm[this.prop] += value ? 1 : -1; this._isSelected = value; } } } export class MyViewModel { items = []; itemsSelected = 0; // that''s the property we''ll pass to the class we''ve created constructor() { for (let i = 0; i < 50; i++) { // instead of adding a annonymous {} here, we add an instance of our class this.items.push(new Item(this, ''itemsSelected'', `Item ${i+1}`)); } } toggleIsSelected(item) { item.isSelected = !item.isSelected; } }

He creado un plunker para usted: http://plnkr.co/edit/OTb2RDLZHf5Fy1bVdCB1?p=preview

Al hacer eso, nunca harás bucles para ver si algún elemento ha cambiado.

Estoy utilizando Aurelia y tengo una serie de elementos vinculados a una cuadrícula y tienen una propiedad seleccionada en ellos. Quiero enlazar un botón para que se habilite cuando cualquiera de los elementos es verdadero. Puedo hacer un enfoque de fuerza bruta en el que tengo un captador que está filtrando la lista y devolviendo los elementos seleccionados, pero eso significa que estaría haciendo una comprobación sucia constantemente en la aplicación y no quiero hacerlo. Espero un enfoque más eficiente. ¿Algunas ideas?


Creo que también puedes aprovechar EventAggregator como se muestra here . De esa manera, no es necesario realizar comprobaciones sucias todo el tiempo y, en cambio, manejar el evento de selección de elementos en su propia VM y publicar los datos de eventos; el suscriptor en el otro lado escuchará lo mismo y realizará la gimnasia necesaria.

Sin embargo, nunca lo he usado, por lo que no estoy seguro de los detalles más profundos. Pero a partir de la documentación parece bastante fácil.


Jeremy me hizo pensar en esto en este error . Así que parece que también puede obtener la actualización de enlace a través de un comportamiento de enlace personalizado. Espero que Jeremy pueda confirmar que no estoy haciendo nada demasiado tonto aquí.

Utilizado de esta manera:

repeat.for="item of items | filter & array:''propertyName''"

Anula el comportamiento estándar de observación y observa en la matriz y la propiedad que define en cada elemento. Probablemente pueda mejorarse para ser más genérico ...

function observeProperty(obj, property) { this.standardObserveProperty(obj, property); let value = obj[property]; if (Array.isArray(value)) { this.observeArray(value); for(let each of value){ this.standardObserveProperty(each, this.propertyName); } } } export class ArrayBindingBehavior { bind(binding, source, property) { binding.propertyName = property; binding.standardObserveProperty = binding.observeProperty; binding.observeProperty = observeProperty; } unbind(binding, source) { binding.observeProperty = binding.standardObserveProperty; binding.standardObserveProperty = null; delete binding.propertyName; } }


Pocas cosas que podría hacer, asumiendo que tengo su caso de uso correcto:

revisión sucia (es solo una propiedad, no es un gran problema)

export class Item { selected = false; } export class ViewModel { items = [new Item(), new Item(), new Item()]; get anySelected() { var items = this.items, i = items.length; while(i--) { if (items[i].selected) { return true; } } return false; } }

observar los artículos

import {BindingEngine, inject} from ''aurelia-framework''; export class Item { selected = false; } @inject(BindingEngine) export class ViewModel { items = [new Item(), new Item(), new Item()]; anySelected = false; subscriptions = []; constructor(locator) { this.bindingEngine = bindingEngine; } updateAnySelected() { var items = this.items, i = items.length; while(i--) { if (items[i].selected) { this.anySelected = true; return; } } this.anySelected = false; } activate() { var items = this.items, i = items.length, observer; while(i--) { observer = this.bindingEngine.propertyObserver(items[i], ''selected''); subscriptions.push(observer.subscribe(() => this.updateAnySelected()); } this.updateAnySelected(); } deactivate() { let dispose; while(subscription = subscriptions.pop()) { subscription.dispose(); } } }

usar una clase de colección

import {computedFrom} from ''aurelia-framework''; export class Item { _selected = false; constructor(parent) { this.parent = parent; } @computedFrom(''_selected'') get selected() { return this._selected; } set selected(newValue) { newValue = !!newValue; if (newValue === _selected) { return; } _selected = newValue; this.parent.itemChanged(newValue); } } export class Items { items = []; selectedCount = 0; anySelected = false; createItem() { let item = new Item(this); this.items.push(item); return item; } itemChanged(selected) { this.selectedCount += (selected ? 1 : -1); this.anySelected = this.selectCount > 0; } } export class ViewModel { items = new Items(); constructor() { let item = this.items.createItem(); item = this.items.createItem(); item = this.items.createItem(); } }

Usa una matriz de SelectedItems en lugar de un prop booleano seleccionado.

export class ViewModel { items = [{}, {}, {}]; selectedItems = []; selectItem(item) { this.items.push(item); } deselectItem(item) { this.items.splice(this.items.indexOf(item), 1); } }

para fines vinculantes, use selectedItems.length como su propiedad "cualquier seleccionado"