CanJS - issue #1231

can.compute nested key behaviour inconsistency with map bindings

by prometh

HTML

<script src="http://canjs.us/release/latest/can.jquery.js"></script>
<script src="http://canjs.us/release/latest/can.construct.proxy.js"></script>
<script src="http://canjs.us/release/latest/can.control.plugin.js"></script>
<script src="http://canjs.us/release/latest/can.view.modifiers.js"></script>
<script src="http://canjs.us/release/latest/can.construct.super.js"></script>
<script src="http://canjs.us/release/latest/can.object.js"></script>
<script src="http://canjs.us/release/latest/can.ejs.js"></script>
<script src="http://canjs.us/release/latest/can.map.attributes.js"></script>
<script src="http://canjs.us/release/latest/can.map.backup.js"></script>
<script src="http://canjs.us/release/latest/can.map.delegate.js"></script>
<script src="http://canjs.us/release/latest/can.map.setter.js"></script>
<script src="http://canjs.us/release/latest/can.map.validations.js"></script>
<script src="http://canjs.com/release/latest/can.fixture.js"></script>
<script src="http://canjs.com/release/latest/can.stache.js"></script>
<script id="main" type="text/handlebars">
    {{#isState "page1"}}<app-page1 files="{files}"/>{{/isState}}
    {{#isState "page2"}}page 2{{/isState}}
</script>

<script id="page1" type="text/handlebars">
    page1
</script>

JavaScript

can.Component.extend({
    tag: "app-main",
    template: can.view("main"),
    scope: {
        files: [],
        state: can.compute( function() {
            console.log( "app-main:scope:state", this.attr("files") );
            
            // Works with this.attr("files").attr("length")
            // Works with this.attr("files.0")
            if ( this.attr("files.length") ) {
                return "page2";
            }
            
            return "page1";
        })
    },
	helpers: {
        isState: function(stateName, options) {
            if (this.attr("state") == stateName) {
                return options.fn(options.scope, options.options);
            } else {
                return options.inverse(options.scope, options.options);
            }
        }
    }
});


can.Component.extend({
    tag: "app-page1",
    template: can.view("page1"),
    init: function() {
        setTimeout( function() {
            console.log("app-page1:init:timeout");
            
            // Update app-main:files
            this.scope.files.push("test");
            
        }.bind(this), 1000);
    }
});


can.append( can.$(document.body), can.stache("<app-main/>")() );