Доступ к свойству объекта от слушателя события звонит в JavaScript

использовать этот класс

public class WCFs
{
    //  https://192.168.30.8/myservice.svc?wsdl
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "192.168.30.8";
private static final String SERVICE = "/myservice.svc?wsdl";
private static String SOAP_ACTION = "http://tempuri.org/iWCFserviceMe/";


public static Thread myMethod(Runnable rp)
{
    String METHOD_NAME = "myMethod";

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

    request.addProperty("Message", "Https WCF Running...");
    return _call(rp,METHOD_NAME, request);
}

protected static HandlerThread _call(final RunProcess rp,final String METHOD_NAME, SoapObject soapReq)
{
    final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    int TimeOut = 5*1000;

    envelope.dotNet = true;
    envelope.bodyOut = soapReq;
    envelope.setOutputSoapObject(soapReq);

    final HttpsTransportSE httpTransport_net = new HttpsTransportSE(URL, 443, SERVICE, TimeOut);

    try
    {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() // use this section if crt file is handmake
        {
            @Override
            public boolean verify(String hostname, SSLSession session)
            {
                return true;
            }
        });

        KeyStore k = getFromRaw(R.raw.key, "PKCS12", "password");
        ((HttpsServiceConnectionSE) httpTransport_net.getServiceConnection()).setSSLSocketFactory(getSSLSocketFactory(k, "SSL"));


    }
    catch(Exception e){}

    HandlerThread thread = new HandlerThread("wcfTd"+ Generator.getRandomNumber())
    {
        @Override
        public void run()
        {
            Handler h = new Handler(Looper.getMainLooper());
            Object response = null;

            for(int i=0; i<4; i++)
            {
                response = send(envelope, httpTransport_net , METHOD_NAME, null);

                try
                {if(Thread.currentThread().isInterrupted()) return;}catch(Exception e){}

                if(response != null)
                    break;

                ThreadHelper.threadSleep(250);
            }

            if(response != null)
            {
                if(rp != null)
                {
                    rp.setArguments(response.toString());
                    h.post(rp);
                }
            }
            else
            {
                if(Thread.currentThread().isInterrupted())
                    return;

                if(rp != null)
                {
                    rp.setExceptionState(true);
                    h.post(rp);
                }
            }

            ThreadHelper.stopThread(this);
        }
    };

    thread.start();

    return thread;
}


private static Object send(SoapSerializationEnvelope envelope, HttpTransportSE androidHttpTransport, String METHOD_NAME, List<HeaderProperty> headerList)
{
    try
    {
        if(headerList != null)
            androidHttpTransport.call(SOAP_ACTION + METHOD_NAME, envelope, headerList);
        else
            androidHttpTransport.call(SOAP_ACTION + METHOD_NAME, envelope);

        Object res = envelope.getResponse();

        if(res instanceof SoapPrimitive)
            return (SoapPrimitive) envelope.getResponse();
        else if(res instanceof SoapObject)
            return ((SoapObject) envelope.getResponse());
    }
    catch(Exception e)
    {}

    return null;
}

public static KeyStore getFromRaw(@RawRes int id, String algorithm, String filePassword)
{
    try
    {
        InputStream inputStream = ResourceMaster.openRaw(id);
        KeyStore keystore = KeyStore.getInstance(algorithm);
        keystore.load(inputStream, filePassword.toCharArray());
        inputStream.close();

        return keystore;
    }
    catch(Exception e)
    {}

    return null;
}

public static SSLSocketFactory getSSLSocketFactory(KeyStore trustKey, String SSLAlgorithm)
{
    try
    {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustKey);

        SSLContext context = SSLContext.getInstance(SSLAlgorithm);//"SSL" "TLS"
        context.init(null, tmf.getTrustManagers(), null);

        return context.getSocketFactory();
    }
    catch(Exception e){}

    return null;
}

}

22
задан Ronald 4 July 2009 в 04:35
поделиться

5 ответов

Когда вызывается обработчик событий, this больше не ссылается на объект someObj. Вам необходимо записать «this» в локальную переменную, которую будет захватывать функция mouseMoving.

var someObj = function someObj(){
    this.prop = 33;
    var self = this;
    this.mouseMoving = function() { console.log(self.prop);}

    document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}

Я предполагаю, что «someObj является конструктором, то есть предназначен для вызова с помощью as new someObj () , в противном случае "this" будет глобальной областью действия.

Ключевое слово "this" может сбивать с толку в JavaScript, потому что оно не работает так же, как в других языках. Главное, что следует помнить, это то, что оно привязано к вызывающему объект , когда функция вызывается , а не когда функция создается.

23
ответ дан 29 November 2019 в 04:40
поделиться

Для этой цели предназначена встроенная функция JavaScript Function.prototype.bind ().
Например:

var someObj = function someObj(){
       this.prop = 33;
        this.mouseMoving = function() { console.log(this.prop);}

        document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving.bind(this),true);

 }

Подробнее о методе привязки здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

В противном случае у вас есть передать ссылку объекта someObj на элемент и использовать эту ссылку в строке:

console.log(this.referenceToObject.prop); //this references the DOM element in an event.
8
ответ дан 29 November 2019 в 04:40
поделиться

В объявлении функции есть опечатки.

Ваша переменная prop также определена как "общедоступный" или "видимый" член (с помощью this.prop), это заставляет вас сохранить ссылку на this из внешней функции (которая на самом деле является ссылкой на экземпляр объекта) как "частный" член функции (используя var), чтобы получить доступ к экземпляру созданного объекта и прочитать член "public" prop .

У вас есть несколько альтернатив, чтобы переписать этот код:

function someObj (){
    var self = this;
    this.prop = 33;
    this.mouseMoving = function() { alert(self.prop);} // You access the current
                                                       // instance, stored in *self*
                                                       // since *this*, inside the 
                                                       // function, is in another 
                                                       // context.
    //...
}

var mySomeObj = new someObj(); // Object instantiation

Или вы could:

function someObj (){
    var prop = 33;
    this.mouseMoving = function() { alert(prop);} 

    //...
}
var mySomeObj = new someObj(); // Object instantiation

Переменные, объявленные с помощью var , доступны для функций, объявленных внутри основной функции конструктора, эта функция известна как Closures .

0
ответ дан 29 November 2019 в 04:40
поделиться

Из раздела 4.3 JavaScript: Хорошие моменты от Дугласа Крокфорда :

Вызов функции приостанавливает выполнение текущей функции, передача управления и параметров в новая функция. В добавок к объявленные параметры, каждая функция получает два дополнительных параметра: это и аргументы. Параметр this очень важно в объектно-ориентированном программирование, и его ценность определяется шаблоном вызова. Есть четыре модели призыва в JavaScript: вызов метода шаблон, вызов функции шаблон, вызов конструктора шаблон, а вызов apply шаблон. Узоры отличаются тем, как бонусный параметр это инициализирована.

Крокфорд продолжает объяснять привязку this в каждом из этих шаблонов следующим образом:

Шаблон вызова метода: Когда функция сохраняется как свойство объекта, мы называем ее методом. Когда вызывается метод, он привязывается к этому объекту.

Шаблон вызова функции: Когда функция вызывается с этим шаблоном, она привязывается к глобальному объекту. Это было ошибкой при разработке языка.

Шаблон вызова конструктора: Если функция вызывается с новым префиксом, то будет создан новый объект со скрытой ссылкой на значение члена прототипа функции, и он будет привязан к этому новому объекту.

Шаблон вызова Apply: ] Метод apply позволяет нам создать массив аргументов для вызова функции. Это также позволяет нам выбирать значение this. Метод apply принимает два параметра. Первое - это значение, которое должно быть связано с этим. Второй - это массив параметров.

5
ответ дан 29 November 2019 в 04:40
поделиться

Во-первых, вам нужно понять, как 'this' работает в JavaScript. Ключевое слово this не ведет себя так, как в других языках, таких как C # или JAVA. Прочтите следующий пост, чтобы понять больше,

Каково обоснование поведения ключевого слова this в JavaScript?

Как только вы поймете, что, как Матфей обрисовал в своем коде, вы можете сохранить ссылку на this и используйте эту ссылку внутри функции mouseMoving.

Хотя в целом, я советую вам использовать среду JavaScript (например, jQuery, YUI, MooTools), которая позаботится об этих проблемах за вас. Например, в Internet Explorer вы используете addEvent для присоединения события, а не addEventListenr.

3
ответ дан 29 November 2019 в 04:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: