数组在forEach聚合物属性观察者中变为“未定义”

时间:2016-12-08 14:21:12

标签: javascript arrays foreach polymer undefined

我有一个让我疯狂的问题,我无法理解为什么会这样。

我有一个自定义的Polymer元素,在这个元素中我设置了一个带有函数的数组,在这个元素中我有一个纸张输入,其值绑定到一个变量,该变量有一个观察者,每次都是变量更改我运行一个迭代数组并执行一些简单检查的函数。一切正常,直到输入值进入6-9范围,此时迭代的数组变为'undefined',直到我退出该范围,我将一个观察者附加到该数组,奇怪的是当数组变为'undefined'时'观察者没有被解雇,所以我猜实际数组没有改变。

这是代码

    <link rel="import" href="../custom_elements/paper-file-input.html">
<link rel="import" href="../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="../bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="../bower_components/paper-item/paper-item.html">
<dom-module id="property-editor">

    <style>

        :host{
            height: 100%;
            width: 100%;
        }

        .background {
            background: #565456;
            padding: 8pt;
        }

        .full{
            width: 100%;
            height:100%;
        }

        .title{
            color: white;
            font-size: 14pt;
        }

        .prop{
            --paper-input-container-color: white;
            --paper-input-container-focus-color: #e8745c;
            --paper-input-container-input-color: white;
        }

    </style>

    <template style="width:100%; height:100%;">
        <div class="background full">
            <p class="roboto title"><b>PROPRIETA':</b></p>
            <template is="dom-if" if="{{selected}}">
                <div class="altfullright" style="overflow:auto;">
                    <span class="roboto propsec">Tempo:</span>
                    <div style="display:flex; align-items:center;">
                        <paper-input class="prop" style="width:100%; margin-right:8pt;" type="number" label="Da" value="{{from}}" min="0" max="100"></paper-input>
                        <paper-input class="prop" style="width:100%;" type="number" label="A" value="{{to}}" min="0" max="100"></paper-input>
                    </div>
                    <span class="roboto propsec">Posizione:</span>
                    <div style="display:flex; align-items:center;">
                        <paper-input class="prop" style="width:100%; margin-right:8pt;" type="number" label="Left" value="{{left}}" min="0" max="1000"></paper-input>
                        <paper-input class="prop" style="width:100%;" type="number" label="Top" value="{{top}}" min="0" max="1000"></paper-input>
                    </div>
                    <span class="roboto propsec">Generale:</span>
                    <paper-input class="prop" label="Nome" value="{{nome}}"></paper-input>
                    <template is="dom-if" if="{{_or(button, link, text)}}">
                        <paper-input class="prop" label="Testo" value="{{testo}}"></paper-input>
                    </template>
                    <template is="dom-if" if="{{_or(button, link, text)}}">
                        <span class="roboto propsec">Testo:</span>
                        <paper-input class="prop" type="number" label="Dimensione font" min="0" max="100"></paper-input>
                        <paper-color-input allow-alpha class="prop" shape="square" type="hsl" label="Colore font"></paper-color-input>
                        <paper-dropdown-menu class="prop" label="Famiglia font">
                            <paper-listbox class="dropdown-content">
                                <paper-item>Roboto</paper-item>
                                <paper-item>Arial</paper-item>
                                <paper-item>Common Sans</paper-item>
                            </paper-listbox>
                        </paper-dropdown-menu>
                    </template>
                    <span class="roboto propsec">Elemento:</span>
                    <paper-file-input class="prop" label="Sfondo"></paper-file-input>
                    <paper-color-input allow-alpha class="prop" shape="square" type="hsl" label="Colore sfondo"></paper-color-input>
                </div>
                <div>
                    <paper-button raised class="fullwidth white" on-tap="_handleTimestamp">AGGIORNA</paper-button>
                </div>
            </template>
            <template is="dom-if" if="{{!selected}}">
                <div class="altfullright" style="overflow:auto;">
                    <span class="roboto propsec" style="font-size:12pt;">Seleziona un elemento</span>
                </div>
                <div>
                    <paper-button raised disabled class="fullwidth white">AGGIORNA</paper-button>
                </div>
            </template>
        </div>
    </template>

    <script>
        Polymer({
            is: 'property-editor',

            properties:{
                nome:{
                    type:String,
                    observer: '_nameChanged'
                },
                selected:{
                    type:Boolean
                },
                testo:{
                    type:String,
                    observer: '_textChanged'
                },
                from:{
                    type:String,
                    observer: '_fromChanged'
                },
                to:{
                    type:String,
                    observer: '_toChanged'
                },
                left:{
                    type:Number,
                    observer: '_leftChanged'
                },
                top:{
                    type:Number,
                    observer: '_topChanged'
                },
                timestamps:{
                    type:Array,
                    observer: '_timeChanged'
                }
            },

            ready: function(){
                this.selected = false;
                var app = this;
                $(document).on('element-selected', function(e){
                    app._handleSelection(e.detail.selected);
                });
            },

            _retrieveOverlayTimestamps: function(){
                var app = this;
                $.ajax({
                    url: 'php/get-timestamp.php',
                    method: 'POST',
                    data: {'id': app.id},
                    success: function(data){
                        var result = JSON.parse(data);
                        this.timestamps = result;
                    }
                });
            },

            _timeChanged: function(newValue, oldValue){
                console.log("Changed to: "+newValue);
            },

            _or: function(condition, other){
                if(condition || other){
                    return true;
                }
                return false;
            },

            _or: function(condition, other, third){
                if(condition || other || third){
                    return true;
                }
                return false;
            },

            _fromChanged: function(newValue, oldValue){
                if(newValue < this.to){
                    this.timestamps.forEach(function (elem) {
                        if(newValue >= elem.from && newValue < elem.to){
                            this.timevalid = false;
                        }else if(newValue < elem.from && this.to >= elem.to){
                            this.timevalid = false;
                        }
                    });
                }else{
                    this.timevalid = false;
                }
                console.log(this.timevalid);
            },

            _toChanged: function(newValue, oldValue){
                if(this.from < newValue){
                    this.timestamps.forEach(function (elem) {
                        if(newValue < elem.to && newValue >= elem.from){
                            this.timevalid = false;
                        }
                    });
                }else{
                    this.timevalid = false;
                }
                console.log(this.timevalid);
            },

            _leftChanged: function(newValue, oldValue){

            },

            _topChanged: function(newValue, oldValue){

            },

            _nameChanged: function(){
                var app = this;
                $.ajax({
                    url: 'php/update-elem.php',
                    method: 'POST',
                    data: {'property':'overlay_name', 'value':this.nome, 'id':app.id},
                    success: function(){
                        app.fire('element-changed');
                    }
                });
            },

            _textChanged: function(){
                var app = this;
                $.ajax({
                    url: 'php/update-elem.php',
                    method: 'POST',
                    data: {'property': 'overlay_props', 'value':this.testo, 'id':app.id},
                    success: function(){
                        app.fire('element-changed');
                    }
                });
            },

            _handleTimestamp: function(e){

            },

            _handleSelection: function(index){
                this.selected = true;
                this.timevalid = true;
                this.id = index;
                this._retrieveOverlayTimestamps();
                var app = this;
                $.ajax({
                    url:"php/get-selected.php",
                    method: 'POST',
                    data: {'id':index},
                    success: function(data){
                        var result = JSON.parse(data);
                        var element = result[0];
                        var elementstr = $(result[0].type);
                        var tagName = $(elementstr).prop("tagName");
                        app.nome = element.name;
                        app.testo = $(elementstr).html();
                        app.from = element.from;
                        app.to = element.to;
                        app.left = element.x;
                        app.top = element.y;
                        if( tagName == "PAPER-BUTTON" ){
                            if($(element).hasClass('link')){
                                app.link = true;
                                app.button = false;
                                app.image = false;
                                app.text = false;
                            }else{
                                app.link = false;
                                app.button = true;
                                app.image = false;
                                app.text = false;
                            }
                        }
                    }
                });
            }
        });
    </script>

</dom-module>

当我输入6-9范围时引发的错误就是这个错误

property-editor.html:183 Uncaught TypeError: Cannot read property 'forEach' of undefined

请帮助,我不知所措......

由于

1 个答案:

答案 0 :(得分:2)

Ajax调用中的this

_retrieveOverlayTimestamps: function(){
    var app = this;
    $.ajax({
        url: 'php/get-timestamp.php',
        method: 'POST',
        data: {'id': app.id},
        success: function(data){
            var result = JSON.parse(data);
            this.timestamps = result;   //<-- wrong
        }
    });
}

应该是

app.timestamps = result;