Attributes can be configured to be `readOnly`, stopping them from being modified by the end user, or `writeOnce` allowing them to be set by the end user, but only once. This example demonstrates how to setup attributes for your class as `readOnly` or `writeOnce` attributes, and shows how their behavior differs when the end user attempts to set their values.
Attribute supports the ability to configure attributes to be `readOnly` or `writeOnce`. `readOnly` attributes cannot be set by the end user, either through initial values passed to the constructor, or by invoking the `set` method. `writeOnce` attributes on the other hand, can be set by the user, but only once, either during initialization or through a call to `set`. Once a value is established for a `writeOnce` attribute, it cannot be reset to another value by the user.
This example sets up a custom class, `MyClass`, with two attributes, `foo` and `bar`. `foo` is configured to be a `readOnly` attribute, and `bar` is configured to be a `writeOnce` attribute:
``` // Setup a custom class with attribute support function MyClass(cfg) { // Attribute configuration var attrs = { "foo" : { value: "Default Foo", readOnly: true }, "bar" : { value: "Default Bar", writeOnce: true } } this.addAttrs(attrs, cfg); } ```We first attempt to set values for both attributes in the constructor (used to intialize the attributes) and see that only `bar`, the `writeOnce` attribute, gets set to the user provided value:
``` var fooVal = Y.one("#writeInitial .fooVal").get("value"); var barVal = Y.one("#writeInitial .barVal").get("value"); o1 = new MyClass({ foo: fooVal, bar: barVal }); displayValues(o1, "Attempt to set initial values in constructor", "#writeInitial .example-out"); ```We then attempt to set values for both attributes again, using `set`, and see that niether of the values are modified:
``` var fooVal = Y.one("#writeAgain .fooVal").get("value"); var barVal = Y.one("#writeAgain .barVal").get("value"); // Attempt to reset values: o1.set("foo", fooVal); o1.set("bar", barVal); displayValues(o1, "Attempt to set values again, using set", "#writeAgain .example-out"); ```Although the user cannot update the value of `readOnly` attributes, it maybe neccessary for the host object to update it's value internally. The example shows how this can be done, using the private `_set` property on the host:
``` MyClass.prototype.doSomething = function(val) { // ... Do something which requires // MyClass to change the value // of foo ... // Host code can reset value of // readOnly attributes interally, // by working with the private _set // property this._set("foo", val); }; ... var val = Y.one("#writeInternally .fooVal").get("value"); // Call method, which sets foo internally... o1.doSomething(val); displayValues(o1, "Set value of foo (readOnly) interally", "#writeInternally .example-out"); ```