0

私はこの問題が死んだことを知っていますが、私はまだそれを理解していません. 私は、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);
    }
});
});

回答後に更新:

したがって、これを解決したのは 1 つの答えではなく、2 つの組み合わせでした。バッファローの答えを取り入れました

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

とクレイグの答えに対するバッファローのコメント

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

しかし、クレイグもここで働いていたでしょう。これはタミルの答えと相まって、私もうまくいったと確信しています。

そのため、Buffalo's を回答としてマークしますが、3 つすべては、今後の読者のために検討する価値があります。

4

3 に答える 3

1

The hitch method in dojo/_base/lang is going to be your best friend here. What I assume the findTask function does is exceucte some asynchronous request and then invokes the 2nd param with the results.

First, add dojo/_base/lang to your Dependency list.

Then, change the line

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

to

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

What lang#hitch does is take the first parameter (in this case the instance of your widget), and make it be the scope when the second parameter executes. In this case we want showResults to execute in the current scope.

于 2013-07-03T20:02:02.960 に答える