-- observers 와의 차이점
1. computed 메소드는 값을 리턴 
2. 가상 속성
3. argument로 설정된 모든 property 값이 정의 될 때 까지 ( !== undefined 때 까지) 호출되지 않음

ex 1)

    <cc-grid-toolbar title-text="[[title01]]" i18n-disabled>
        <sc-button id="btnDel"  text="삭제"     on-click="onBtnClick"   hidden="[[!formula('isEditable')]]"></sc-button>
        <sc-button id="btnSave" text="저장"     on-click="onBtnClick"   hidden="[[!formula('isEditable')]]"></sc-button>
    </cc-grid-toolbar>


    <cc-grid-toolbar title-text="[[title02]]" i18n-disabled></cc-grid-toolbar>
    properties : {
        apprData : {
            type: Object,
            value: function() {
                return {};
            }
        },
        resultList : {
            type: Array,
            value: function() {
                return [];
            }
        },
        title01 : {
            type : String,
            computed : "computedLabel01(apprData.appr_no)"
        },
        title02 : {
            type : String,
            computed : "computedLabel02(apprData.dc_appr_no)"
        }
    },


    computedLabel01 : function(title)
    {
        var me = this;
        
        return UT.formatString("{0} ({1} : {2})", me.translate("그리드1"), me.translate("문서번호"), UT.nvl(title, ""));
    },

    computedLabel02 : function(title)
    {
        var me = this;
        
        return UT.formatString("{0} ({1} : {2})", me.translate("그리드2"), me.translate("문서번호"), UT.nvl(title, ""));
    },

ex 2)

            <sc-button auth-r id="btnSwch"      on-click="onBtnClick"   text="[[elementLable.bidBox]]" i18n-disabled></sc-button>
            <sc-button auth-r id="btnSwch2"     on-click="onBtnClick"   text="[[elementLable.bdgtBox]]" i18n-disabled></sc-button>

            <div hidden="[[elementHidden.bidBox]]">
            </div>

            <div hidden="[[elementHidden.bdgtBox]]">
            </div>
            properties : {
...
                elementHidden : {
                    type : Object,
                    value : function() {
                        return {
                            bidBox  : true,
                            bdgtBox : false
                        }
                    },
                },
                elementLable : {
                    type : Object,
                    computed : "computedElementLable(elementHidden)"
                },
...
            },

            computedElementLable : function(elementHidden)
            {
                var me = this;
                
                var _label = {};
                _label.bidBox   = elementHidden.bidBox  ? "Tab Navi On" : "Tab Navi Off";
                _label.bdgtBox  = elementHidden.bdgtBox ? "예가 On"       : "예가 Off";
                
                me.$.tabNavi.doContentElementResize();

                return _label;
            },

            onBtnClick : function(event)
            {
                var me = this;
                
                switch (event.target.id)
                {
                    case "btnSwch" :
                        me.set("elementHidden.bidBox", !me.elementHidden.bidBox);
                        me.set("elementHidden", UT.copy(me.elementHidden));
                        break;

                    case "btnSwch2" :
                        me.set("elementHidden.bdgtBox", !me.elementHidden.bdgtBox);
                        me.set("elementHidden", UT.copy(me.elementHidden));
                        break;
                }
            },