I’m using Shoelace in a Aurelia 2 app . The ‘sl-input’ component value.two-way binding cause an error.
here is the code and errors.
<sl-input label="phone" value.two-way="user.phone" ></sl-input>
error:
utilities.ts:22 Uncaught (in promise) Error: Trying to set value for property value in dirty checker
at createError (utilities.ts:22:49)
at DirtyCheckProperty.setValue (dirty-checker.ts:142:11)
at PropertyBinding.updateTarget (property-binding.ts:74:27)
at PropertyBinding.bind (property-binding.ts:144:12)
at Controller.bind (controller.ts:609:26)
at Controller.activate (controller.ts:593:10)
at ComponentAgent.Mt (component-agent.ts:69:31)
at viewport-agent.ts:523:38
at Transition.Qt (router.ts:81:19)
at viewport-agent.ts:521:18
If I use ‘value.bind’ or ‘value.from-view’, it works as expected. ‘value.bind’ works the same as ‘value.one-way’ in this case.
Any one can help?
It should be similar like the integration of other lib mentioned here Integration | The Aurelia 2 Docs
Thanks! The microsoft FAST example works well! Here is the code for shoelace in case others might need it.(not fully tested):
const shoelaceAdapter = (container) => {
const attrMapper = container.get(IAttrMapper);
const nodeObserverLocator = container.get(NodeObserverLocator);
attrMapper.useTwoWay((el, property) => {
switch (el.tagName) {
case 'SL-INPUT':
case 'SL-SELECT':
case 'SL-TEXTAREA':
case 'SL-RADIO':
case 'SL-RADIO-GROUP':
return property === 'value';
case 'SL-CHECKBOX':
case 'SL-SWITCH':
return property === 'checked';
case 'SL-TAB':
return property === 'active';
default:
return false;
}
});
// Teach Aurelia what events to use to observe properties of elements.
// Because FAST components all use a single change event to notify,
// we can use a single common object
const valuePropertyConfig = { events: ['sl-input', 'sl-change'] };
nodeObserverLocator.useConfig({
'SL-CHECKBOX': {
checked: valuePropertyConfig
},
'SL-RADIO': {
value: valuePropertyConfig
},
'SL-RADIO-GROUP': {
value: valuePropertyConfig
},
'SL-INPUT': {
value: valuePropertyConfig
},
'SL-SWITCH': {
checked: valuePropertyConfig
},
'SL-TAB': {
active: valuePropertyConfig
},
'SL-SELECT': {
value: valuePropertyConfig
},
'SL-TEXTAREA': {
value: valuePropertyConfig
}
})
}
Aurelia
.register(AppTask.creating(IContainer, shoelaceAdapter))
.app(MyApp)
.start();
I have also tried the Ionic example , It didn’t work. I have noticed that the only difference lies in the registration part. FYI.
This does NOT work:
export class ShoelaceFramework implements IRegistry {
register(container: IContainer) {
const attrMapper = container.get(IAttrMapper);
const nodeObserverLocator = container.get(NodeObserverLocator);
attrMapper.useTwoWay((el, property) => {
console.log("two way bind...");
if (el.tagName === 'SL-CHECKBOX' ||
el.tagName === 'SL-TOGGLE'
) {
return property === 'checked';
}
return el.tagName.startsWith('SL') && property === 'value';
});
const valuePropertyConfig = { events: ['sl-input','sl-change'] };
nodeObserverLocator.useConfig({
'SL-INPUT': {
value: valuePropertyConfig
}
});
return container;
}
}
Aurelia
.register(ShoelaceFramework)
.app(MyApp)
.start();
2 Likes
@zhanglongyu can you help with a PR to add an example of shoelace integration to the doc? Will definitely be welcomed and a source of help for others.
I would love to do that, but I am not familiar with PR process. I read the contributor guide, still don’t know where to start.