Javascript 变量范围问题 - 错误 : TypeError: this. 图形未定义

标签 javascript dojo undefined scope

我知道这个问题已经搞死了,但是我还是不明白。我读过 StackOverFlow 自己的 "this" keyword解释(以及其中的 Mike West 文章)以及其他与范围相关的问题。我不知道为什么我不明白,所以我向更精明的 JavaScript 开发人员寻求帮助。

从代码和注释来看,它应该是相当不言自明的。但它正在查询 ESRI map 服务,返回图形并将其放置在 map 上。

但问题出在 showResults 函数中,我在其中调用 this.graphics,它是 map 的图形属性(图形图层)。我知道它现在超出了范围(这花费了比我愿意承认的更多的时间来弄清楚),但是我怎样才能将它放回到范围内以便我可以使用它?即使我对代码进行了大幅修改......

define([
"dojo/_base/declare",
"dojo/on",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin",
"dijit/form/Button",
"dijit/form/Form",
"dijit/form/FilteringSelect",
"dijit/form/ValidationTextBox",
"dojo/_base/array",
"dojo/_base/Color",
"dojo/_base/lang",
"esri/tasks/find",
"dojo/text!./Find/templates/Find.html"
], function(declare, on, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, Button, Form, FilteringSelect, ValidationTextBox, array, Color, lang, find, FindTemplate) {

//anonymous function to load CSS files required for this module
(function() {
    var css = [require.toUrl("gis/dijit/Find/css/Find.css")];
    var head = document.getElementsByTagName("head").item(0),
        link;
    for(var i = 0, il = css.length; i < il; i++) {
        link = document.createElement("link");
        link.type = "text/css";
        link.rel = "stylesheet";
        link.href = css[i].toString();
        head.appendChild(link);
    }
}());

// Query Dijit
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
    widgetsInTemplate: true,
    templateString: FindTemplate,
    graphics: null,
    findTask: null,
    findParams: null,
    results: [],
    serverError: null,
    queryLayer: null,
    searchText: null,
    postCreate: function() {
        // Method is used to call a superclass method. It's good practice to assume that you are overriding a method that may 
        // do something important in a class up the inheritance chain
        this.inherited(arguments);

        // Create graphics layer and add it to the map
        this.graphics = new esri.layers.GraphicsLayer({id:"queryGraphics"});
        this.map.addLayer(this.graphics);

        // Create find task with url to map service
        this.findTask = new esri.tasks.FindTask("arcgis/rest/services/MapServer");

        // Create find parameters and define known values
        this.findParams = new esri.tasks.FindParameters();     
        this.findParams.outSpatialReference = this.map.spatialReference;
        this.findParams.returnGeometry = true;
        this.findParams.layerIds = [1];
        this.findParams.searchFields = ["OBJECTID", "Gauge ID", "FV_ID", "FDC_ID", "Flood_Stage", "Flood_Line", "Municipality", "WATERSHED"]; 

        // Listen for Submit button click
        on(this.submitButton, 'click', lang.hitch(this, 'execute'));
    },
    // Submit button click event
    execute: function execute() {   
        // Set the WHERE search text
        this.findParams.searchText = dojo.byId("searchText").value;
        // Sends a request to the ArcGIS REST map service resource to perform a search based 
        // on the FindParameters specified in the findParameters argument. On completion, the 
        // onComplete event is fired and the optional callback function is invoked.
        this.findTask.execute(this.findParams, this.showResults, this.showError); 
    },
    // Fires when the find operation is complete and returns an array of FindResult
    showResults: function showResults(results) {
        this.graphics.clear();
        // Build an array of attribute information and add each found graphic to the map
        dojo.forEach(results, function(result) {
            var symbol;
            switch(result.feature.geometry.type) {
                case "point":
                    symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new Color([255, 0, 0]), 1), new Color([255, 0, 0, 1.0]));
                    break;
                case "polyline":
                    symbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASH, new Color([255, 0, 0]), 1);
                    break;
                case "polygon":
                    symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.0]));
                    break;
                default:
                    symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new Color([255, 0, 0]), 1), new Color([255, 0, 0, 1.0]));
            }
            var graphic = new esri.Graphic(result.feature.geometry, symbol);
            this.graphics.add(graphic);
        });
    },
    // Fires if the find execution fails to complete
    showError: function showError(serverError) {
        alert("The server encountered an error. Error: " + serverError);
    }
});
});

回答后更新:

所以,解决这个问题的不是一个答案,而是两个答案的组合。我合并了 Buffalo 的答案

this.findTask.execute(this.findParams, lang.hitch(this, this.showResults), this.showError);

以及布法罗对克雷格的回答的评论

dojo.forEach(results, function(result) {  
...
}, this);

但克雷格也可以在这里工作。我确信这与泰米尔语的答案相结合也会起作用。

所以我将 Buffalo's 标记为答案,但这三个都值得任何进一步的读者关注。

最佳答案

hitch dojo/_base/lang中的方法将成为你在这里最好的 friend 。我假设findTask函数的作用是执行一些异步请求,然后使用结果调用第二个参数。

首先,添加dojo/_base/lang到您的依赖项列表。

然后,更改线路

this.findTask.execute(this.findParams, this.showResults, this.showError); 

this.findTask.execute(this.findParams, lang.hitch(this,this.showResults), this.showError); 

什么lang#hitch所做的就是获取第一个参数(在本例中是小部件的实例),并使其成为第二个参数执行时的范围。在本例中,我们希望 showResults 在当前范围内执行。

关于Javascript 变量范围问题 - 错误 : TypeError: this. 图形未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17456928/

相关文章:

javascript - MySql 错误 "could not update record"错误号 0 - 当没有更改记录时

internet-explorer - IE 中的 "dojo is undefined"

javascript - 使用 Dojo 时是否需要控制台 shim?

javascript - 想了解更多关于 undefined 的信息

javascript - BokehJS 基本示例错误 - 无法读取未定义的属性 'linspace'

php - 使用 JS 或 PHP 显示文件夹中的随机图像而不重复

javascript - Jquery html() 内部条件检查

javascript - 添加接触计数器 knockout

javascript - 如何使用 Dijit DateTextBox 显示和验证自定义格式?

c - 1 和 0 存在于空 int 数组中