Aurelia repeat.for 使用自定义元素引发未定义错误
Aurelia repeat.for throws an undefined error with custom-element
我想传递一个对象数组。
我正在使用 repeat.for
语法将商店数组从一个自定义元素 'Store' 传递到另一个自定义元素 'store-front'。
我最初调用 store-front
、store
并将其更改为 store-front
以防有帮助 - 但它没有。
我可以在 'store' 自定义元素中记录数组。我还记录了它的实例(它是一个数组)。
错误如下:
aurelia-task-queue.js?26b6:44 Uncaught TypeError: Cannot set property 'undefined' of undefined
at setKeyed (aurelia-binding.js?1bbb:1923)
at AccessKeyed.assign (aurelia-binding.js?1bbb:1461)
at NameBinder.bind (aurelia-binding.js?1bbb:5174)
at View.bind (aurelia-templating.js?f83c:1396)
at Controller.bind (aurelia-templating.js?f83c:3394)
at View.bind (aurelia-templating.js?f83c:1406)
at Repeat.addView (repeat.js?1ef5:240)
at ArrayRepeatStrategy._standardProcessInstanceChanged (array-repeat-strategy.js?783a:107)
at ArrayRepeatStrategy.instanceChanged (array-repeat-strategy.js?783a:29)
at Repeat.itemsChanged (repeat.js?1ef5:136)
at BehaviorPropertyObserver.selfSubscriber (aurelia-templating.js?f83c:3645)
at BehaviorPropertyObserver.call (aurelia-templating.js?f83c:3512)
at BehaviorPropertyObserver.setValue (aurelia-templating.js?f83c:3492)
at Repeat.descriptor.set [as items] (aurelia-templating.js?f83c:3600)
at Object.setValue (aurelia-binding.js?1bbb:3539)
at Binding.updateTarget (aurelia-binding.js?1bbb:4778)
at Binding.call (aurelia-binding.js?1bbb:4793)
at SetterObserver.callSubscribers (aurelia-binding.js?1bbb:295)
at SetterObserver.call (aurelia-binding.js?1bbb:3612)
at TaskQueue.flushMicroTaskQueue (aurelia-task-queue.js?26b6:140)
at MutationObserver.eval (aurelia-task-queue.js?26b6:68)
我在某处读到,当 Aurelia 附加数组观察器时,它变成了一个对象。但是我找不到任何关于如何处理这个问题的文档。
我可以将商店传递给商店中的普通 div
html - 但我更喜欢 modular/composable.
Stores.js
import { customElement, useView, inject, bindable } from 'aurelia-framework'
import { EventAggregator } from 'aurelia-event-aggregator'
import { DialogService } from 'aurelia-dialog'
import { HttpClient } from 'aurelia-http-client'
import { getStoresTask, toVm } from './model'
import { getStoreTask } from './store-front/model'
import { style } from './style.css'
import { map, clone } from 'ramda'
@customElement('stores')
@useView('./stores.html')
@inject(EventAggregator, HttpClient, DialogService)
export class Stores {
@bindable tenants
@bindable userId
constructor( emitter, http, modal ) {
this.disposables = new Set()
this.data = {}
this.state = {}
this.emitter = emitter
this.http = http
this.errors=[]
this.style=style
}
attached() {
this.reset()
this.getStores()
}
getStores() {
const onError = error =>
console.error(error);
const onSuccess = data => {
this.data.stores = data
console.log(this.data.stores)
this.emitter.publish('loading-channel', false)
}
this.emitter.publish('loading-channel', true)
getStoresTask(this.http)(this.userId).fork(onError, onSuccess)
}
// openModal(id) {
// this.this.modal.open( {viewModel: Store, model: id })
// }
reset() {
}
}
Stores.html
<template>
<require from="material-design-lite/material.css"></require>
<require from="./store-front/store-front"></require>
<div class="store-collection">
<div class=" mdl-grid">
<store-front repeat.for="store of data.stores" store-front.bind="store"></store-front>
</div>
</div>
</template>
商店-front.js
import { customElement, useView, inject, bindable } from 'aurelia-framework'
import { DialogController } from 'aurelia-dialog'
import { HttpClient } from 'aurelia-http-client'
import { getStoreTask } from './model.js'
import { style } from './style.css'
@customElement('store-front')
@useView('./store-front.html')
@inject(HttpClient, DialogController)
export class StoreFront {
@bindable storeFront
constructor( http, dController ) {
this.disposables = new Set()
this.dController = dController
this.store = ''
this.id = null
this.state = {}
this.http = http
this.style = style
}
attached() {
this.reset()
this.getStore()
}
getStore(id) {
const onError = error => {
console.error(error);
this.errors.push({type:'store', msg: 'error with getting store'})
}
const onSuccess = store => {
this.store = store
this.errors['store'] = ''
this.openModal(id)
this.emitter.publish('loading-channel', false)
}
this.emitter.publish('loading-channel', true)
getStoreTask(this.http)(id).fork(onError, onSuccess)
}
colorChange() {
// console.log(typeof this.storeColors);
// TODO: grab b/ style and create a fucntion that chnages the color based on another input
changeStoreColors(this.storeColors)
}
reset() {
console.log('store?',this.store)
}
}
商店-front.html
<template>
<div class="mdl-cell mdl-shadow--2dp mdl-grid__item mdl-grid__item--three-div" css="${style.storeColor}" ref="storeColors[$index]"}>
<span class="mdl-grid__item-primary-content">
<svg style="width:24px;height:24px" viewBox="0 0 24 24">
<path fill="#000000" d="M9,19V13H11L13,13H15V19H18V10.91L12,4.91L6,10.91V19H9M12,2.09L21.91,12H20V21H13V15H11V21H4V12H2.09L12,2.09Z" />
</svg>
<span>${store.name}</span>
<span class="mdl-grid__item-text-body">
<p>Expiration Date: ${store.expirationDate} <br>
Notification Date: ${store.notificationDate}</p>
</span>
</span>
<span class="mdl-grid__item-secondary-content">
<a class="mdl-grid__item-secondary-action" href="#"><i class="material-icons">star</i></a>
<button class="mdl-button mdl-button--compact mdl-button--theme-dark mdl-card__action mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" click.delegate="showStore(store._id)">MORE DETAIL</button>
</span>
</li>
</div>
<template >
更新:
堆栈追溯到 .ref
绑定。首先检查所有 ref
绑定。这里还有一个与 ref
和继承相关的问题,如果你 运行 遇到同样的问题 https://github.com/aurelia/templating/issues/533
,你可以看看
原文:
看起来这一行是您 store.html
中的问题
<store-front repeat.for="store of data.stores" store-front.bind="data.stores"></store-front>
请注意 store-front.bind=data.stores
,您绑定到数组而不是 data.stores
中的每个商店。
我很确定问题是由两件事引起的:
您正在尝试访问您视图中 data
的 stores
属性,即使此 属性 不存在于数据绑定时间。
您正在使用 attached
回调来调用 getStores
。
我首先为 data
对象中的 stores
属性 创建一个空数组:
this.data = { stores: [] }
我会改用 bind
回调而不是 attached
。
最后,您可能需要添加一个 if.bind="data.stores.length > 0" to the
store-front` 元素:
<store-front if.bind="data.stores.length > 0"
repeat.for="store of data.stores"
store-front.bind="store"></store-front>
在这种情况下,重要的是将 if.bind
放在 repeat.for
之前,以便它优先。
如果有帮助请告诉我!
我想传递一个对象数组。
我正在使用 repeat.for
语法将商店数组从一个自定义元素 'Store' 传递到另一个自定义元素 'store-front'。
我最初调用 store-front
、store
并将其更改为 store-front
以防有帮助 - 但它没有。
我可以在 'store' 自定义元素中记录数组。我还记录了它的实例(它是一个数组)。
错误如下:
aurelia-task-queue.js?26b6:44 Uncaught TypeError: Cannot set property 'undefined' of undefined
at setKeyed (aurelia-binding.js?1bbb:1923)
at AccessKeyed.assign (aurelia-binding.js?1bbb:1461)
at NameBinder.bind (aurelia-binding.js?1bbb:5174)
at View.bind (aurelia-templating.js?f83c:1396)
at Controller.bind (aurelia-templating.js?f83c:3394)
at View.bind (aurelia-templating.js?f83c:1406)
at Repeat.addView (repeat.js?1ef5:240)
at ArrayRepeatStrategy._standardProcessInstanceChanged (array-repeat-strategy.js?783a:107)
at ArrayRepeatStrategy.instanceChanged (array-repeat-strategy.js?783a:29)
at Repeat.itemsChanged (repeat.js?1ef5:136)
at BehaviorPropertyObserver.selfSubscriber (aurelia-templating.js?f83c:3645)
at BehaviorPropertyObserver.call (aurelia-templating.js?f83c:3512)
at BehaviorPropertyObserver.setValue (aurelia-templating.js?f83c:3492)
at Repeat.descriptor.set [as items] (aurelia-templating.js?f83c:3600)
at Object.setValue (aurelia-binding.js?1bbb:3539)
at Binding.updateTarget (aurelia-binding.js?1bbb:4778)
at Binding.call (aurelia-binding.js?1bbb:4793)
at SetterObserver.callSubscribers (aurelia-binding.js?1bbb:295)
at SetterObserver.call (aurelia-binding.js?1bbb:3612)
at TaskQueue.flushMicroTaskQueue (aurelia-task-queue.js?26b6:140)
at MutationObserver.eval (aurelia-task-queue.js?26b6:68)
我在某处读到,当 Aurelia 附加数组观察器时,它变成了一个对象。但是我找不到任何关于如何处理这个问题的文档。
我可以将商店传递给商店中的普通 div
html - 但我更喜欢 modular/composable.
Stores.js
import { customElement, useView, inject, bindable } from 'aurelia-framework'
import { EventAggregator } from 'aurelia-event-aggregator'
import { DialogService } from 'aurelia-dialog'
import { HttpClient } from 'aurelia-http-client'
import { getStoresTask, toVm } from './model'
import { getStoreTask } from './store-front/model'
import { style } from './style.css'
import { map, clone } from 'ramda'
@customElement('stores')
@useView('./stores.html')
@inject(EventAggregator, HttpClient, DialogService)
export class Stores {
@bindable tenants
@bindable userId
constructor( emitter, http, modal ) {
this.disposables = new Set()
this.data = {}
this.state = {}
this.emitter = emitter
this.http = http
this.errors=[]
this.style=style
}
attached() {
this.reset()
this.getStores()
}
getStores() {
const onError = error =>
console.error(error);
const onSuccess = data => {
this.data.stores = data
console.log(this.data.stores)
this.emitter.publish('loading-channel', false)
}
this.emitter.publish('loading-channel', true)
getStoresTask(this.http)(this.userId).fork(onError, onSuccess)
}
// openModal(id) {
// this.this.modal.open( {viewModel: Store, model: id })
// }
reset() {
}
}
Stores.html
<template>
<require from="material-design-lite/material.css"></require>
<require from="./store-front/store-front"></require>
<div class="store-collection">
<div class=" mdl-grid">
<store-front repeat.for="store of data.stores" store-front.bind="store"></store-front>
</div>
</div>
</template>
商店-front.js
import { customElement, useView, inject, bindable } from 'aurelia-framework'
import { DialogController } from 'aurelia-dialog'
import { HttpClient } from 'aurelia-http-client'
import { getStoreTask } from './model.js'
import { style } from './style.css'
@customElement('store-front')
@useView('./store-front.html')
@inject(HttpClient, DialogController)
export class StoreFront {
@bindable storeFront
constructor( http, dController ) {
this.disposables = new Set()
this.dController = dController
this.store = ''
this.id = null
this.state = {}
this.http = http
this.style = style
}
attached() {
this.reset()
this.getStore()
}
getStore(id) {
const onError = error => {
console.error(error);
this.errors.push({type:'store', msg: 'error with getting store'})
}
const onSuccess = store => {
this.store = store
this.errors['store'] = ''
this.openModal(id)
this.emitter.publish('loading-channel', false)
}
this.emitter.publish('loading-channel', true)
getStoreTask(this.http)(id).fork(onError, onSuccess)
}
colorChange() {
// console.log(typeof this.storeColors);
// TODO: grab b/ style and create a fucntion that chnages the color based on another input
changeStoreColors(this.storeColors)
}
reset() {
console.log('store?',this.store)
}
}
商店-front.html
<template>
<div class="mdl-cell mdl-shadow--2dp mdl-grid__item mdl-grid__item--three-div" css="${style.storeColor}" ref="storeColors[$index]"}>
<span class="mdl-grid__item-primary-content">
<svg style="width:24px;height:24px" viewBox="0 0 24 24">
<path fill="#000000" d="M9,19V13H11L13,13H15V19H18V10.91L12,4.91L6,10.91V19H9M12,2.09L21.91,12H20V21H13V15H11V21H4V12H2.09L12,2.09Z" />
</svg>
<span>${store.name}</span>
<span class="mdl-grid__item-text-body">
<p>Expiration Date: ${store.expirationDate} <br>
Notification Date: ${store.notificationDate}</p>
</span>
</span>
<span class="mdl-grid__item-secondary-content">
<a class="mdl-grid__item-secondary-action" href="#"><i class="material-icons">star</i></a>
<button class="mdl-button mdl-button--compact mdl-button--theme-dark mdl-card__action mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" click.delegate="showStore(store._id)">MORE DETAIL</button>
</span>
</li>
</div>
<template >
更新:
堆栈追溯到 .ref
绑定。首先检查所有 ref
绑定。这里还有一个与 ref
和继承相关的问题,如果你 运行 遇到同样的问题 https://github.com/aurelia/templating/issues/533
原文:
看起来这一行是您 store.html
<store-front repeat.for="store of data.stores" store-front.bind="data.stores"></store-front>
请注意 store-front.bind=data.stores
,您绑定到数组而不是 data.stores
中的每个商店。
我很确定问题是由两件事引起的:
您正在尝试访问您视图中
data
的stores
属性,即使此 属性 不存在于数据绑定时间。您正在使用
attached
回调来调用getStores
。
我首先为 data
对象中的 stores
属性 创建一个空数组:
this.data = { stores: [] }
我会改用 bind
回调而不是 attached
。
最后,您可能需要添加一个 if.bind="data.stores.length > 0" to the
store-front` 元素:
<store-front if.bind="data.stores.length > 0"
repeat.for="store of data.stores"
store-front.bind="store"></store-front>
在这种情况下,重要的是将 if.bind
放在 repeat.for
之前,以便它优先。
如果有帮助请告诉我!