Javascript变量作用域问题-错误:类型错误:this.graphics未定义
Javascript Variable Scope Issue - Error: TypeError: this.graphics is undefined
我知道这个问题已经解决了,但我仍然不明白。我已经阅读了StackOverFlow自己的"this"关键字解释(以及其中的Mike West文章)以及其他与范围相关的问题。我不知道为什么我不明白,所以我向更精明的JavaScript开发人员寻求帮助。
从代码和注释来看,它应该是不言自明的。但它正在查询ESRI地图服务,返回图形并将其放置在地图上。
但问题出在showResults
函数中,我调用this.graphics
,这是地图的图形属性(图形层)。我知道它现在超出了范围(我花了比我想承认的更多的时间来弄清楚),但我如何才能把它放回范围,这样我才能使用它?即使我大幅修改了代码。。。
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);
}
});
});
回答后更新:
所以,解决这个问题的不是一个答案,而是两个答案的结合。我把布法罗对的回答纳入其中
this.findTask.execute(this.findParams, lang.hitch(this, this.showResults), this.showError);
布法罗对克雷格回答的评论
dojo.forEach(results, function(result) {
...
}, this);
但克雷格的也会在这里工作。再加上泰米尔语的回答,我确信这也会奏效。
所以我会把布法罗的作为答案,但这三本书都值得更多读者阅读。
dojo/_base/lang
中的hitch
方法将成为您最好的朋友。我假设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#hutch所做的是获取第一个参数(在本例中是小部件的实例),并在执行第二个参数时使其成为作用域。在这种情况下,我们希望showResults在当前范围内执行。
您可以使用Function.bind(注意!并非所有浏览器都支持它)。
更改:
this.findTask.execute(this.findParams, this.showResults, this.showError);
收件人:
this.findTask.execute(this.findParams, this.showResults.bind(this), this.showError);
或者(如果您关心Function.bind
浏览器支持):
使用closure
&Function.apply
execute: function execute() {
...
...
var self = this;
this.findTask.execute(this.findParams, function() {
self.showResults.apply(self, arguments);
}, this.showError);
}
您的问题在于以下代码
dojo.forEach(results, function(result) {
...
this.graphics.add(graphic);
});
正在执行的功能不具有小部件的作用域。成功:
dojo.forEach(results, lang.hitch(this, function(result) {
}));
- 错误:this.setValues不是js代码中的函数,请使用googlemapapi
- 为什么会出现错误$this没有定义
- jqueryui:"类型错误:this.menu.element未定义"
- 引导使用谷歌图形错误:this.q.Ee不是中的函数
- 未捕获的类型错误:this.reset不是函数-在ajax调用后清空输入时出错
- 错误:this.getToken 不是一个函数
- 未捕获的类型错误:this.getKeyCode 不是一个函数
- 未捕获类型错误:this.context.router.push不是函数
- Javascript未定义错误:“this”为null
- 类型错误:this.io是未定义的套接字.io.js:639
- JQuery手风琴类型错误:this.slideshow未定义
- 未捕获类型错误:this.source不是函数coffeescript错误
- 未捕获类型错误:this.props.data.map不是函数(使用超级代理)
- Javascript变量作用域问题-错误:类型错误:this.graphics未定义
- 未捕获的类型错误:this.transitionTo不是函数
- 未捕获的类型错误:this.$.AjaxPost.go不是一个以函数为核心的ajax
- 呼叫'FaceNormalsHelper'导致'类型错误:this.update不是函数'
- Javascript类型错误:this.init不是一个函数
- 主干错误'this.模型未定义',请解释'this.model'
- 未捕获的类型错误:$this.文本不是函数