Paul Ryan
Paul Ryan

Reputation: 1509

Binding to a Namespaced Attribute in Aurelia

When bind to attributes(one-way) there are a couple of options you can either bind with attr-name.bind="variable" (also tried one-way and one-time) or using interpolation attr-name="${variable}", either way though if you try to bind to a namespaced element such as xlink:href you currently get:

Uncaught NamespaceError: Failed to execute 'setAttributeNS' on 'Element': '' is an invalid namespace for attributes.

For have the following in a controller page.js:

export class page {
    constructor(){
        this.icon = 'blah';
    }
}

and the following in page.html:

<template>
  <svg class="icon ${icon}">
    <use xlink:href="${icon}"></use>
  </svg>
</template>

As I said either of the bind's above is throwing the given error.

Any thoughts on how to bind to this namespaced attribute?

Instrumented the bootstrap handleApp function to print the full stack trace:

Error: Failed to execute 'setAttributeNS' on 'Element': '' is an invalid namespace for attributes. at Error (native) at OoPropertyObserver.setValue (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/property-observation.js:200:26) at InterpolationBinding.setValue (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/binding-language.js:214:35) at InterpolationBinding.bind (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/binding-language.js:202:22) at View.bind (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/view.js:65:29) at ViewFactory.create (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/view-factory.js:173:22) at BoundViewFactory.create (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/view-factory.js:128:39) at Repeat.processItems (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/repeat.js:105:36) at Repeat.bind (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/repeat.js:60:22) at BehaviorInstance.bind (http://localhost:9000/jspm_packages/github/aurelia/[email protected]/system/behavior-instance.js:67:39)

Also if I hack the property-observation code to explicitly set the namespace it works, but this is really kludgy and likely to break quickly.

https://github.com/aurelia/binding/blob/master/src/property-observation.js#L153-L159 changed to:

setValue(newValue) {
    if (this.isSVG) {
      if(this.propertyName.indexOf('xlink:') >= 0){
        this.obj.setAttributeNS("http://www.w3.org/1999/xlink", this.propertyName, newValue);
      } else {
        this.obj.setAttributeNS(null, this.propertyName, newValue);
      }
    } else {
      this.obj[this.propertyName] = newValue;
    }
}

Upvotes: 4

Views: 603

Answers (1)

Paul Ryan
Paul Ryan

Reputation: 1509

Handling for namespaced elements in aurelia is now explicitly supported thanks to https://github.com/aurelia/binding/issues/34. No need to do anything special. This works for HTML and HTML5 issues with namespacing.

Upvotes: 3

Related Questions